MySQL 排序规则类型是不是需要匹配 PHP 页面字符集类型?

Posted

技术标签:

【中文标题】MySQL 排序规则类型是不是需要匹配 PHP 页面字符集类型?【英文标题】:Does MySQL collation type need to match PHP page charset type?MySQL 排序规则类型是否需要匹配 PHP 页面字符集类型? 【发布时间】:2010-10-25 12:48:54 【问题描述】:

我已开始调试我的 RSS 提要,因为其中包含一些奇怪的字符(即缺少字符的字形)。我从两个优秀的初学者资源开始:

每个软件开发人员绝对、绝对必须了解 Unicode 和字符集的绝对最低要求:http://www.joelonsoftware.com/articles/Unicode.html 字符集/字符编码问题:http://www.phpwact.org/php/i18n/charsets

我认为我们的 RSS 提要有问题的原因是用户将 MS Word 文档复制并粘贴到网站上的文本区域中,而我们的 PHP 页面使用的“iso-8859-1”字符集与特殊的“Windows”不兼容-1252" 编码,用于 MS Word 使用的项目符号和智能引号等内容。

所以我希望解决这个问题,我需要做的就是在接受/提供用户输入的页面中开始使用“utf-8”?? IE。在 HEAD 部分设置以下内容:

<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

我提出这个问题的真正原因是因为我存储用户输入的数据库字段位于“latin1_swedish_ci”中,我想知道是否需要将它们转换为“utf8_general_ci”? mysql 并不真正关心字符集吗?它只看到一堆字节,如果我将 Unicode 放入一个整理为拉丁语的字段中,它仍然会以 Unicode 的形式出现,对吗?更改字段会很烦人,因为该字段是 FULLTEXT 索引的一部分,其中其他字段也需要更改其排序规则,这意味着删除索引并重建它(当涉及大量 TEXT 时,这不是一项小任务)。

【问题讨论】:

【参考方案1】:

不 - 绝对不是。由于 MySQL 具有动态将字符串从一个字符集转换为另一个字符集的能力,尽管您的 MySQL 服务器知道您在客户端使用什么字符集(客户端 = PHP 脚本,NOT 客户端访问您的网页)。这可以通过发出查询来完成

SET NAMES 'utf8';

在您发送到服务器的任何其他查询之前。然后,MySQL 将执行从您的客户端字符集到内部 MySQL 字符集到表和/或列字符集的适当转换,并一直返回。所以通常你只需要担心设置正确的客户端字符集。此字符集必须与您用于将数据输出到网络服务器的字符集匹配。

请查看 MySQL 手册:

9.1.4. Connection Character Sets and Collations 或9.1. Character Set Support。

【讨论】:

【参考方案2】:

在 HTTP 中,字符编码由 HTTP 响应的 Content-Type header field 中的 charset 参数声明。 Other declaration are overwritten by the declaration in the HTTP header:

[...] 用户代理在确定文档的字符编码时必须遵守以下优先级(从最高优先级到最低优先级):

    Content-Type”字段中的 HTTP“charset”参数。 META 声明,其中“http-equiv”设置为“Content-Type”,值设置为“charset”。 在指定外部资源的元素上设置的 charset 属性。

此外,您应该在form 元素中使用accept-charset attribute 显式声明接受的字符编码。否则,用户代理可以(但不能)采用表单文档中使用的字符编码来对输入数据进行编码:

此属性的默认值为保留字符串“UNKNOWN”。用户代理可以将此值解释为用于传输包含此FORM 元素的文档的字符编码。

这应该为您提供正确编码传入数据的最佳机会。但它没有保证。所以最好检查一下数据是否是用 UTF-8 编码的(有函数/算法可以做到这一点)。

【讨论】:

【参考方案3】:

我提出这个问题的真正原因是因为我存储用户输入的数据库字段位于“latin1_swedish_ci”中,我想知道是否需要将它们转换为“utf8_general_ci”?

没有。 latin1_swedish_ciutf8_general_ci 是排序规则 - 不是字符集。排序规则不会影响字符存储或输入/输出的方式。它只控制排序函数如何对其结果进行排序。排序规则 - 按预期工作 - 应该与存储字符集匹配。因此,如果您的表存储在 utf8 中,则应使用 utf8 排序规则。

mysql 的存储字符集不直接绑定到 php 中的字符集。您可以使用 utf8 作为 Mysql 的存储字符集,而在 php.ini 中使用 iso-8859-1。在这种情况下,您需要通过在连接上设置字符集 (set names XXX) 来告诉 Mysql。然后 Mysql 将根据需要进行转换。如果你不在 Mysql 和 php 上使用相同的字符集,你最终会得到作为最低 dommon 分母的字符集容量,所以即使字符串存储在 utf8 中,你也不会拥有完整的 unicode 字符范围可用的。因此你应该在both Mysql 和 php 中使用 utf8。

【讨论】:

【参考方案4】:

为了节省一些时间来搜索如何使用 pdo/mysql 很好地更改 mysql 连接字符集,我是这样做的:

$dbc = new pdo('mysql:dbname=DBNAME;host=DBHOST', $user, $pw, array(PDO::MYSQL_ATTR_INIT_COMMAND => sprintf( "SET NAMES %s", $charset ) ) );

【讨论】:

以上是关于MySQL 排序规则类型是不是需要匹配 PHP 页面字符集类型?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL ---- 索引类型 & 使用规则 & 回表覆盖索引 & 设计索引考虑因素

哪个 MySQL 排序规则与 PHP 的字符串比较完全匹配?

PHP PHP函数改变MySQL数据库的排序规则

(转)mysql数据库中存储数字字段时,选择int和varchar的区别

分库分表后的分页查询

PHP函数更改MySQL数据库的排序规则