【问题标题】:With PHP and MySQL, how do I properly write smart quotes to the database?使用 PHP 和 MySQL,如何正确地将智能引号写入数据库?
【发布时间】:2012-01-22 19:46:13
【问题描述】:

我有一个 PHP 网站,上面有 CLEditor richtext control。当我尝试将欧元和英镑写入数据库时​​,该字符运行良好,因为我在包含页面 HTML、富文本控件 IFRAME HTML 和 MySQL 表排序规则中将字符集设置为 UTF-8。在这方面一切都很好。然而,当我尝试写 smart quotes 时,我最终在数据库中看到了这个输出:

This is a “testâ€.

(如果在您的浏览器上方没有正确显示,则测试词有类似拉丁语 a、欧元符号和单词前面的小 AE 符号,以及拉丁语 a 和欧元符号之后。)

当我使用 PHP 从数据库中读取该值以将其显示在页面上时,它最终显示为带有问号的黑色菱形以及一些其他拉丁字符。

我应该怎么做才能解决这个问题?

【问题讨论】:

    标签: php mysql utf-8 unicode-normalization cleditor


    【解决方案1】:

    首先,确保您的 MySQL 表使用 UTF-8 作为其编码。如果是,它将如下所示:

    mysql> SHOW CREATE TABLE Users (
    ...
    ) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8 |
    

    接下来,确保您的 HTML 页面设置为显示 UTF-8:

    <html>
        <head>
            <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
        </head>
        ....
    </html>
    

    那么它应该可以工作了。


    编辑:我故意不谈论排序规则,因为我认为它已经被考虑过了,但是为了大家的利益,让我在这个答案中添加更多内容。

    你说,

    我在 MySQL 表排序规则中将字符集设置为 UTF-8 ...。

    表格排序规则与字符集不同。

    排序规则是自动尝试将一个字符集转换为另一个出于查询目的的行为。例如,如果您有一个 latin1 字符集和一个 UTF-8 排序规则,并且您执行 SELECT * FROM foo WHERE bar LIKE '%—%'; 之类的操作。 (UTF-8 U+2014) 在具有 latin1 字符集的表上匹配 L+0151 U+2014。

    并非如此巧合...如果您将此 latin1 编码的字符输出到 UTF-8 编码的网页上,您将得到以下信息:

    这是一个“测试”。

    这似乎是您的问题的输出,确切地说。这是复制它的 HTML:

    <?php
    $string = "This is a “test”.";
    ?>
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html;charset=utf8"/>
        </head>
        <body>
            <p><?php echo $string; ?></p>
        </body>
    </html>
    

    确保将此文件保存在 latin1...

    要查看您的表设置的字符集,请运行以下查询:

    SELECT CCSA.character_set_name, TABLE_COLLATION FROM information_schema.`TABLES` T,
           information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` CCSA
    WHERE CCSA.collation_name = T.table_collation
      AND T.table_schema = "database"
      AND T.table_name = "table";
    

    唯一适合您使用的结果(除非您使用多种非英语语言)是:

    +--------------------+-----------------+
    | character_set_name | TABLE_COLLATION |
    +--------------------+-----------------+
    | utf8               | utf8_general_ci |
    +--------------------+-----------------+
    

    感谢您的支持;-)

    【讨论】:

    • 不要生硬,因为我很欣赏你高度聪明的回答,西奥多——你过去帮助我解决了一些 PHP OOP 问题,并给出了很好的答案。然而,在这里回应——去过那里,做到了。我已经在我的帖子中提到了这一点。请注意,大多数其他 UTF-8 内容已经可以使用。只是那些聪明的引语显得很时髦。
    • 老实说,我没有看到你说你在哪里尝试过上述方法。我已经重读了它,但仍然看不到你提到这个的地方;/我向你展示了常见的问题。第三步是检查您输入的字符。但我想你已经想到了那个。我猜我错了。
    • "当我尝试将欧元和英镑写入数据库时​​,字符通过就好了,因为我在包含页面 HTML 中将字符集设置为 UTF-8,在富文本控件 IFRAME HTML 中,并且在 MySQL 表排序规则中。在这方面一切都很好。”
    【解决方案2】:

    在打印任何内容之前,确保您的 PHP 文件在顶部有这个。我可以将 latin_swedish_ci 带入一个 utf8 编码的网站,它可以正确编码。

    header("Content-type: text/html;charset=UTF-8");

    我也把它放在我的数据库连接之后(不确定这是否同样重要):

    mysql_query("SET NAMES 'utf8'");<br>mysql_query("SET CHARACTER SET 'utf8'");

    【讨论】:

      【解决方案3】:

      对于阅读这篇文章的其他人来说,我发现添加这些 mysqld 配置行 - 如果您可以访问 mysql 服务器并且可以进行更改 - 解决了我的弯引号问题。

      http://dev.mysql.com/doc/refman/5.6/en/charset-server.html

      # Force UTF8 Charset Encoding
      skip-character-set-client-handshake
      collation_server=utf8_unicode_ci
      character_set_server=utf8
      

      我已经仔细检查了从 PHP 调用的 SQL(看起来不错),并且还从我的 GUI 中手动执行了带有花括号的插入/更新语句(效果很好),但仍然从 Web 服务器获取多控制字符插入数据库。

      我检查了我的 mysql 服务器变量,发现 latin1 是服务器和数据库的默认值(即使表/列是 UTF8)。一旦我添加了上面的行并刷新了发出更新语句的页面,花括号确实插入正确。我只能假设这与我们服务器的默认字符集为 latin1 和 Web 服务器 mysql 库握手协商有关。

      【讨论】:

        【解决方案4】:

        如别人所说,先解决以下两个问题:

        • 将您的数据库转换为 UTF-8。
        • 发送 UTF-8 HTTP 标头。

        如果您在命令行中遇到“test†的问题STILL,在转换数据库之后,请确保在之前在您的 SSH linux CLI 中运行它运行mysql...

        export LANG=en_US.UTF-8
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-25
          • 1970-01-01
          • 2015-03-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多