使用PHP操纵MySQL的utf8mb4数据

时间:2012-10-23 10:36:18

标签: php mysql cjk utf8mb4

这可能很简单。我发誓我一直在网上寻找答案而没有找到答案。由于我的特殊情况有点不典型,我终于决定在这里问。

我在MySQL中有一些表用于中文程序。它需要能够支持所有可能的汉字,包括没有很好字体支持的稀有字符。表中的示例单元格可能是:

  

东菄鸫䍶倲涷蝀冻鯟崠埬䰤

为了让它在数据库中正常工作,我必须将编码/整理设置为utf8mb4。到现在为止还挺好。不幸的是,当我将相同的字符串拉入PHP时,它会被打印出来:

  

东菄鸫䍶?倲??涷蝀冻鯟?崠埬?䰤

我怎样才能最终杀掉剩下的问号并让它们显示为unicode字形?我已经在标签中使用UTF8编码并将其作为元标记。

为什么他们不能互相沟通?我做错了什么?

2 个答案:

答案 0 :(得分:15)

我只是猜测您将表格设置为utf8mb4,但您的连接编码设置为utf8。您还必须将其设置为utf8mb4,否则MySQL会将存储的utf8mb4数据转换为utf8,后者不能编码“高”Unicode字符。 (是的,这是MySQL的特质。)

在原始MySQL连接上,它必须如下所示:

SET NAMES 'utf8mb4';
SELECT * FROM `my_table`;

根据您从PHP(mysql,mysqli或PDO)连接到MySQL的方式,您必须根据客户端的最佳方式进行调整。


要真正澄清(是的,为了简单起见使用mysql_扩展名,请不要在家中执行此操作):

mysql_connect(...);
mysql_select_db(...);
mysql_set_charset('utf8mb4');     // adapt to your mysql connector of choice

$r = mysql_query('SELECT * FROM `my_table`');

var_dump(mysql_fetch_assoc($r));  // data will be UTF8 encoded

答案 1 :(得分:2)

为了添加@deceze的答案,我推荐一个配置良好的MySQL服务器(对我来说,在/etc/mysql/mysql.conf.d/mysqld.cnf中)。以下是确保您使用utfmb4的配置选项,虽然我建议您仔细检查每个MySQL配置选项,但实际上令人生畏,有很多默认值非常不理想

[client]

default-character-set           = utf8mb4

[mysql]

default_character_set           = utf8mb4

[mysqld]

init-connect                    = "SET NAMES utf8mb4"
character-set-client-handshake  = FALSE
character-set-server            = "utf8mb4"
collation-server                = "utf8mb4_unicode_ci"
autocommit                      = 1
block_encryption_mode           = "aes-256-cbc"

最后一个只是一个应该是默认的。此外,init-connect处理不必每次都执行该操作。保持代码清洁。现在运行:

SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';

您应该返回以下内容:

+--------------------------+--------------------+
| Variable_name            | Value              |
+--------------------------+--------------------+
| character_set_client     | utf8mb4            |
| character_set_connection | utf8mb4            |
| character_set_database   | utf8mb4            |
| character_set_filesystem | binary             |
| character_set_results    | utf8mb4            |
| character_set_server     | utf8mb4            |
| character_set_system     | utf8               |
| collation_connection     | utf8mb4_unicode_ci |
| collation_database       | utf8mb4_unicode_ci |
| collation_server         | utf8mb4_unicode_ci |
+--------------------------+--------------------+

看起来你已经这样做了,但明确定义表创建并不会有什么坏处:

CREATE TABLE `mysql_table` (
  `mysql_column` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`mysql_column`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4;

希望这有助于某人。