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