84669 人学习
152542 人学习
20005 人学习
5487 人学习
7821 人学习
359900 人学习
3350 人学习
180660 人学习
48569 人学习
18603 人学习
40936 人学习
1549 人学习
1183 人学习
32909 人学习
我正在设置一个新的服务器,并希望在我的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 meta标签(或在作为XML提供的XHTML的情况下使用XML声明)。
数据存储:
在数据库中的所有表和文本列上指定utf8mb4字符集。这样,MySQL会以UTF-8的原生编码方式物理存储和检索值。请注意,如果指定了utf8mb4_*排序规则(而没有明确指定字符集),MySQL将隐式使用utf8mb4编码。
utf8mb4
utf8mb4_*
在旧版本的MySQL(< 5.5.3)中,你只能使用仅支持Unicode字符子集的utf8。我希望我在开玩笑。
utf8
数据访问:
在应用程序代码(例如PHP)中,无论你使用什么数据库访问方法,你都需要将连接字符集设置为utf8mb4。这样,MySQL在将数据传递给应用程序和反之时不会对其进行任何转换。
一些驱动程序提供了自己的机制来配置连接字符集,这既更新了其自身的内部状态,也通知MySQL在连接上使用的编码方式-这通常是首选的方法。在PHP中:
如果你使用的是PHP ≥ 5.3.6的PDO抽象层,你可以在DSN中指定charset:
charset
$dbh = new PDO('mysql:charset=utf8mb4');
如果你使用的是mysqli,你可以调用set_charset():
set_charset()
$mysqli->set_charset('utf8mb4'); // 面向对象风格 mysqli_set_charset($link, 'utf8mb4'); // 过程化风格
如果你被困在纯mysql中,但恰好运行的是PHP ≥ 5.2.3,你可以调用mysql_set_charset。
mysql_set_charset
如果驱动程序没有提供自己的设置连接字符集的机制,你可能需要发出一个查询来告诉MySQL你的应用程序希望如何对待连接上的数据编码:SET NAMES 'utf8mb4'。
SET NAMES 'utf8mb4'
与上述相同的关于utf8mb4/utf8的注意事项也适用于此处。
输出:
Content-Type: text/html; charset=utf-8
default_charset
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的链接中有一些很好的资源,可以学习你需要知道的一切。
我想在chazomaticus的出色回答中再补充一点:
也不要忘记META标签(像这样,或者它的HTML4或XHTML版本):
这看起来很琐碎,但IE7以前曾给我带来问题。
我做的一切都是正确的;数据库、数据库连接和Content-Type HTTP头都设置为UTF-8,在所有其他浏览器中都正常工作,但是Internet Explorer仍然坚持使用“西欧”编码。
结果发现页面缺少META标签。添加了之后问题解决了。
编辑:
W3C实际上有一个相当大的专门用于国际化(I18N)的部分。他们有很多与这个问题相关的文章 - 描述了HTTP、(X)HTML和CSS的方面:
他们建议同时使用HTTP头和HTML meta标签(或在作为XML提供的XHTML的情况下使用XML声明)。
数据存储:
在数据库中的所有表和文本列上指定
utf8mb4
字符集。这样,MySQL会以UTF-8的原生编码方式物理存储和检索值。请注意,如果指定了utf8mb4_*
排序规则(而没有明确指定字符集),MySQL将隐式使用utf8mb4
编码。在旧版本的MySQL(< 5.5.3)中,你只能使用仅支持Unicode字符子集的
utf8
。我希望我在开玩笑。数据访问:
在应用程序代码(例如PHP)中,无论你使用什么数据库访问方法,你都需要将连接字符集设置为
utf8mb4
。这样,MySQL在将数据传递给应用程序和反之时不会对其进行任何转换。一些驱动程序提供了自己的机制来配置连接字符集,这既更新了其自身的内部状态,也通知MySQL在连接上使用的编码方式-这通常是首选的方法。在PHP中:
如果你使用的是PHP ≥ 5.3.6的PDO抽象层,你可以在DSN中指定
charset
:如果你使用的是mysqli,你可以调用
set_charset()
:如果你被困在纯mysql中,但恰好运行的是PHP ≥ 5.2.3,你可以调用
mysql_set_charset
。如果驱动程序没有提供自己的设置连接字符集的机制,你可能需要发出一个查询来告诉MySQL你的应用程序希望如何对待连接上的数据编码:
SET NAMES 'utf8mb4'
。与上述相同的关于
utf8mb4
/utf8
的注意事项也适用于此处。输出:
Content-Type: text/html; charset=utf-8
。你可以通过在php.ini中设置default_charset
(首选)或手动使用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的链接中有一些很好的资源,可以学习你需要知道的一切。