UTF-8 一路走来
我正在设置一个新服务器,并希望在我的Web应用程序中完全支持UTF-8。我过去曾在现有服务器上尝试过此操作,并且似乎总是最终不得不回退到ISO-8859-1。
我究竟需要在哪里设置编码/字符集?我知道我需要配置Apache,MySQL和PHP来做到这一点 - 是否有一些我可以遵循的标准清单,或者可能排除不匹配发生的地方?
这是针对新的Linux服务器,运行MySQL 5,PHP,5和Apache 2。
我正在设置一个新服务器,并希望在我的Web应用程序中完全支持UTF-8。我过去曾在现有服务器上尝试过此操作,并且似乎总是最终不得不回退到ISO-8859-1。
我究竟需要在哪里设置编码/字符集?我知道我需要配置Apache,MySQL和PHP来做到这一点 - 是否有一些我可以遵循的标准清单,或者可能排除不匹配发生的地方?
这是针对新的Linux服务器,运行MySQL 5,PHP,5和Apache 2。
数据存储:
指定数据库中所有表和文本列的字符集。这使得MySQL以物理方式存储和检索以UTF-8本机编码的值。请注意,如果指定了排序规则(没有任何显式字符集),MySQL将隐式使用编码。utf8mb4
utf8mb4
utf8mb4_*
在较旧版本的MySQL(<5.5.3)中,不幸的是,您将被迫简单地使用,它仅支持Unicode字符的子集。我希望我是在开玩笑。utf8
数据访问:
在应用程序代码(例如.PHP)中,无论使用哪种数据库访问方法,都需要将连接字符集设置为 。这样,MySQL在将数据移交给应用程序时,不会从其本机UTF-8进行转换,反之亦然。utf8mb4
一些驱动程序提供了自己的机制来配置连接字符集,该机制既更新了自己的内部状态,又通知MySQL要在连接上使用的编码 - 这通常是首选方法。在 PHP 中:
如果将 PDO 抽象层与 PHP ≥ 5.3.6 一起使用,则可以在 DSN 中指定:charset
$dbh = new PDO('mysql:charset=utf8mb4');
如果您使用的是 mysqli,则可以调用 set_charset()
:
$mysqli->set_charset('utf8mb4'); // object oriented style
mysqli_set_charset($link, 'utf8mb4'); // procedural style
如果您坚持使用普通的mysql,但碰巧≥5.2.3运行PHP,则可以调用mysql_set_charset
。
如果驱动程序没有提供自己的机制来设置连接字符集,则可能必须发出查询以告知MySQL应用程序期望连接上的数据如何编码:设置名称'utf8mb4'
。
关于 /的考虑与上述相同。utf8mb4
utf8
输出:
中设置default_charset
.ini(首选)或使用函数手动实现。Content-Type: text/html; charset=utf-8
header()
json_encode()
JSON_UNESCAPED_UNICODE
输入:
的mb_check_encoding()
可以解决问题,但你必须虔诚地使用它。这真的没有办法解决这个问题,因为恶意客户端可以用他们想要的任何编码提交数据,我还没有找到让PHP可靠地为你做到这一点的技巧。其他代码注意事项:
显然,您将要提供的所有文件(PHP,HTML,JavaScript等)都应该用有效的UTF-8编码。
您需要确保每次处理 UTF-8 字符串时,您都可以安全地执行此操作。不幸的是,这是困难的部分。您可能希望广泛使用PHP的mbstring
扩展。
PHP 的内置字符串操作在默认情况下不是 UTF-8 安全的。使用普通的PHP字符串操作可以安全地执行一些事情(例如串联),但是对于大多数事情,您应该使用等效的函数。mbstring
要知道你在做什么(请阅读:不要搞砸),你真的需要知道UTF-8以及它在尽可能低的水平上是如何工作的。查看 utf8.com 中的任何链接,以获取一些很好的资源来学习您需要了解的所有内容。
我想为chazomaticus的出色答案添加一件事:
不要忘记META标签(就像这样,或者它的HTML4或XHTML版本):
<meta charset="utf-8">
这似乎微不足道,但IE7之前给我带来了问题。
我做对了一切;数据库,数据库连接和内容类型HTTP标头都设置为UTF-8,并且在所有其他浏览器中都可以正常工作,但Internet Explorer仍然坚持使用“西欧”编码。
事实证明,该页面缺少META标记。添加它解决了问题。
编辑:
W3C实际上有一个相当大的部分专门用于I18N。他们有很多与这个问题相关的文章 - 描述了HTTP,(X)HTML和CSS方面的事情:
他们建议同时使用HTTP标头和HTML元标记(或在XHTML作为XML的情况下使用XML声明)。