<!- 关于问题标题的重要信息 关于这个标题,在下面的网址上有过长时间的讨论。 在没有阅读之前,请不要对标题进行任何编辑 https://meta.stackoverflow.com/questions/335327/ --> 我正在建立一个新的服务器,并希望在我的Web应用程序中完全支持UTF-8。我过去曾在现有的服务器上尝试这样做,但最后似乎总是不得不退回到ISO-8859-1。
我到底需要在哪里设置编码/字符集?我知道我需要配置Apache、MySQL和PHP来做到这一点--是否有一些标准的检查表我可以遵循,或者也许可以对不匹配的地方进行故障排除?
这是一个新的Linux服务器,运行MySQL 5、PHP 5和Apache 2。
数据存储。
utf8mb4'字符集。 这使得MySQL在物理上存储和检索以UTF-8编码的值。 注意,如果指定了 "utf8mb4_*"排序(没有任何明确的字符集),MySQL将隐含地使用
utf8mb4`编码。utf8
,它只支持Unicode字符的一个子集。 我希望我是在开玩笑。
数据访问。utf8mb4
。 这样,当MySQL将数据移交给你的应用程序时,它不会从其本地的UTF-8进行转换,反之亦然。charset
。
$dbh = new PDO(' mysql:charset=utf8mb4')。set_charset()
。
$mysqli->set_charset('utf8mb4'); // 面向对象的风格
mysqli_set_charset($link, 'utf8mb4'); //程序风格。
*如果你坚持使用普通的mysql,但碰巧运行的是PHP ≥ 5.2.3,你可以调用mysql_set_charset
。SET NAMES 'utf8mb4'
](http://dev.mysql.com/doc/en/charset-connection.html)。
*关于utf8mb4
/utf8
的考虑与上述相同。
输出。default_charset
php.ini选项,或者自己手动发布Content-Type
MIME头,这只是更多的工作,但有同样的效果。json_encode()
对输出进行编码时,添加JSON_UNESCAPED_UNICODE
作为第二个参数。
输入。
*不幸的是,在你试图存储或在任何地方使用它之前,你应该验证每一个收到的字符串是否是有效的UTF-8。 PHP的mb_check_encoding()
可以做到这一点,但你必须虔诚地使用它。 这其实是没有办法的,因为恶意的客户可以用任何他们想要的编码来提交数据,而且我还没有找到一个让PHP可靠地做这件事的技巧。<form>
标签上添加accept-charset
属性。<form ... accept-charset="UTF-8">
。
只适用于HTML5之前的HTML:注意W3C的HTML规范说,客户端"应该"默认以服务器提供的任何字符集向服务器发送表单,但这显然只是一个建议,因此需要在每一个<form>
标签上明确。
其他代码考虑。mbstring
扩展。
PHP内置的字符串操作在默认情况下不是UTF-8安全的。有些事情可以用普通的PHP字符串操作(比如连接)来安全地完成,但对于大多数事情,应该使用等效的mbstring
函数。
*要知道你在做什么(读作:不把它弄乱),你真的需要了解UTF-8以及它是如何在尽可能低的水平上工作。 请查看utf8.com中的任何一个链接,了解你需要知道的一切。除了在php.ini中设置default_charset
外,你可以在代码中使用header()
在任何输出之前发送正确的字符集。
header('Content-Type: text/html; charset=utf-8');
在PHP中使用Unicode是很容易的,只要你意识到大多数的字符串函数不适用Unicode,有些可能会完全扭曲字符串。PHP认为"字符"是一个字节的长度。有时这是好的(例如,explode()
只寻找一个字节序列并将其作为分隔符--所以寻找什么实际字符并不重要)。但在其他时候,当函数实际上被设计为对*字符工作时,PHP不知道你的文本有多字节的字符,而这些字符是用Unicode找到的。
一个可以检查的好库是phputf8。它重写了所有的"坏"函数,所以可以安全地处理UTF8字符串。也有一些扩展,如mbstring扩展,试图为你做到这一点,但我更喜欢使用库,因为它更便携(但我写的是大众市场产品,所以这对我很重要)。但是phputf8可以在幕后使用mbstring,以提高性能。
在PHP中,你需要使用multibyte functions,或者打开mbstring.func_overload。这样,如果你的字符超过一个字节,像strlen这样的东西就可以工作了。
你还需要确定你的响应的字符集。你可以使用AddDefaultCharset,如上所述,或者编写PHP代码来返回头信息。(或者你可以在你的HTML文档中添加一个META标签)。