8通过

我正在设置一个新的服务器,并且希望在我的Web应用程序中完全支持UTF-8。 过去我在现有的服务器上尝试过,并且似乎最终不得不回退到ISO-8859-1。

我在哪里需要设置编码/字符集? 我知道我需要配置Apache,MySQL和PHP来做到这一点 - 是否有一些我可以遵循的标准清单,或者可能需要排除发生不匹配的问题?

这是一个新的Linux服务器,运行MySQL 5,PHP 5和Apache 2。


数据存储

  • 在数据库中的所有表和文本列上指定utf8mb4字符集。 这使MySQL实际存储和检索以UTF-8本地编码的值。 请注意,如果指定了utf8mb4_*排序规则(没有任何明确的字符集),MySQL将隐式使用utf8mb4编码。

  • 在旧版本的MySQL(<5.5.3)中,不幸的是你不得不仅仅使用utf8 ,它只支持一部分Unicode字符。 我希望我在开玩笑。

  • 数据访问

  • 在您的应用程序代码(例如PHP)中,无论您使用utf8mb4数据库访问方法,都需要将连接字符集设置为utf8mb4 。 这样,MySQL在将数据交给应用程序时不会从其本机UTF-8进行转换,反之亦然。

  • 一些驱动程序提供了自己的配置连接字符集的机制,它们都会更新自己的内部状态并通知MySQL将在连接上使用的编码 - 这通常是首选方法。 在PHP中:

  • 如果您使用PHP≥5.3.6的PDO抽象层,则可以在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,但碰巧运行的是PHP≥5.2.3,则可以调用mysql_set_charset

  • 如果驱动程序没有提供自己的设置连接字符集的机制,那么您可能必须发出一个查询来告诉MySQL您的应用程序期望连接上的数据是如何编码的: SET NAMES 'utf8mb4'

  • 关于utf8mb4 / utf8的相同考虑utf8mb4适用。

  • 输出

  • 如果您的应用程序将文本传输到其他系统,则还需要通知其字符编码。 使用Web应用程序时,必须通知浏览器发送数据的编码(通过HTTP响应标头或HTML元数据)。

  • 在PHP中,您可以使用default_charset php.ini选项,或手动发布Content-Type MIME头,这只是更多的工作,但具有相同的效果。

  • 输入

  • 不幸的是,在你尝试存储或在任何地方使用它之前,你应该验证每个收到的字符串是否为有效的UTF-8。 PHP的mb_check_encoding()有诀窍,但你必须虔诚地使用它。 真的没有办法解决这个问题,因为恶意客户可以用他们想要的任何编码提交数据,而且我还没有发现让PHP可靠地为您做这件事的窍门。

  • 从我阅读当前的HTML规范,下面的子项目不再是现代HTML的必要或者甚至是有效的。 我的理解是,浏览器将使用为文档指定的字符集并提交数据。 但是,如果您的目标是旧版HTML(XHTML,HTML4等),这些点可能仍然有用:

  • 对于仅HTML5之前的HTML:您希望浏览器发送给您的所有数据都是UTF-8。 不幸的是,如果你唯一能够可靠地做到这一点的方法是将accept-charset属性添加到所有<form>标签中: <form ... accept-charset="UTF-8">
  • 对于仅HTML5之前的HTML:请注意,W3C HTML规范指出客户端“应该”默认将表单发送回服务器,无论服务器使用什么字符集,但这显然只是一个建议,因此需要在每一个单独的<form>标签。
  • 其他代码注意事项

  • 显然,所有你要服务的文件(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之前给了我一些问题。

    我做的都是对的; 数据库,数据库连接和Content-Type HTTP头都设置为UTF-8,并且在所有其他浏览器中运行良好,但Internet Explorer仍然坚持使用“西欧”编码。

    原来,页面缺少META标签。 添加解决了这个问题。

    编辑:

    W3C实际上有一个相当大的部分专用于I18N。 他们有许多与这个问题有关的文章 - 描述HTTP,(X)HTML和CSS方面的东西:

  • FAQ:将(X)HTML页面编码更改为UTF-8
  • 在HTML中声明字符编码
  • 教程:XHTML,HTML和CSS中的字符集和编码
  • 设置HTTP字符集参数
  • 他们建议使用HTTP标头和HTML元标签(或者在XHTML作为XML的情况下使用XML声明)。


    除了在php.ini中设置default_charset ,您还可以在任何输出之前使用代码中的header()发送正确的字符集:

    header('Content-Type: text/html; charset=utf-8');
    

    在PHP中使用Unicode很容易,只要您意识到大多数字符串函数不适用于Unicode,并且有些可能会彻底破坏字符串 。 PHP认为“字符”长度为1个字节。 有时候这是可以的(例如, explode()只查找字节序列并将其用作分隔符 - 因此,查找的实际字符无关紧要)。 但是有些时候,当函数实际上是为了处理字符而设计的时,PHP并不知道您的文本具有Unicode字符。

    一个好的图书馆是phputf8。 这将重写所有“坏”函数,以便您可以安全地使用UTF8字符串。 有像mbstring扩展那样的扩展,也尝试为你做这件事,但我更喜欢使用该库,因为它更便携(但我写了大众市场产品,所以这对我很重要)。 但是无论如何,phputf8可以在后台使用mbstring来提高性能。

    链接地址: http://www.djcxy.com/p/4259.html

    上一篇: 8 all the way through

    下一篇: How does one create an index on the date part of DATETIME field in MySql