使用PHP和MySQL,如何正确地将智能引号写入数据库?

时间:2012-01-22 19:46:14

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

我有一个PHP网站,上面有CLEditor richtext control。当我尝试将Euros和British Pounds写入数据库时​​,该字符经过很好的处理,因为我在包含页面HTML,richtext控件IFRAME HTML和MySQL表格排序中将字符集设置为UTF-8。一切都很顺利。但是,当我尝试编写smart quotes时,我最终会在数据库中看到此输出:

This is a “testâ€.

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

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

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

4 个答案:

答案 0 :(得分:3)

首先,确保您的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 ....

表格排序与charset不同。

整理是自动尝试将一个字符集转换为另一个字符集的行为出于查询的目的。例如,如果你有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 |
+--------------------+-----------------+

感谢upvotes; - )

答案 1 :(得分:0)

在打印任何内容之前,请确保您的PHP文件位于顶部。我可以把latin_swedish_ci带到一个utf8编码的网站,它编码正确。

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

我也在我的数据库连接之后放了这个(不确定这是否重要):

mysql_query("SET NAMES 'utf8'");
mysql_query("SET CHARACTER SET 'utf8'");

答案 2 :(得分:0)

对于其他任何人来说,这篇文章的价值是什么,我发现添加这些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)。一旦我添加了上面的行并刷新了发出update语句的页面,就会正确插入引号。我只能假设这与我们服务器的默认字符集latin1和web服务器mysql库握手协商有关。

答案 3 :(得分:-1)

我在这里找到了答案:

https://stackoverflow.com/a/1262210/105539

这似乎也不会打扰我的欧元和英镑字符。