【发布时间】:2016-08-22 00:58:56
【问题描述】:
发现问题
问题似乎是$mysqli->set_charset() 不接受 `utf8mb4' 作为有效编码(正如我在第一次更新中“推测”的那样)。 MySQL 版本是 5.5.41,PHP 版本是 5.4.41(没问题)。
对不起标题,我一直在搜索/阅读问题出在哪里/哪里,我已经对此感到困惑......
我最近开始在 mysql 中使用 utf8mb4。我使用 utf8mb4 作为字符集,使用 utf8mb4_unicode_ci 作为所有表/列的排序规则。
所以我首先改变了:
$mysqli->set_charset('utf8');
到
$mysqli->set_charset('utf8mb4');
确保我的 php 文件为 utf8(我使用 Visual Studio Code,因此文件默认以 UTF-8 创建),并且 php/html 标头设置为 utf8:
index.php
header('Content-type: Text/HTML; Charset=UTF-8');
main.php(包含在 index.php 的末尾)
<meta http-equiv="Content-Type" content="Text/HTML" />
<meta charset="UTF-8" />
问题在于,对于某些表,我必须手动插入数据,并且这些数据按原样存储:带有特殊字符、带重音符号、ñ 等......当我在我的网站上显示这些数据时,我可以看到这些字符 � 已经替换了特殊/重音字符。
所以我的问题是:有什么方法可以在 mysql 中按原样存储数据(不替换/转换特殊/重音字符)并能够正常显示(按原样)?
如果我恢复到$mysqli->set_charset('utf8');,数据显示正常...所以这让我想知道按原样存储 utf-8 字符应该没有问题,并且某处存在一些编码问题...
我正在使用 sqlyog 社区(使用 wine)我在某处读到,有时当您更改某些 db/table 配置时 gui 无法正常工作,唯一的方法是旧方法(自己运行查询) ,但我还没有尝试过。我运行查询来设置所有表/列的字符集和排序规则。
你怎么看?
更新
我开始认为 mysqli 不接受 utf8mb4 作为有效的字符编码,并使用 php 而不是 mysql 的 utf8 ...我也认为 mysql fckd 创建 utf8mb4 而不是更新现有的 utf8 以支持 4 个字节....
当我使用 mysqli charset utf8 进行测试时,所有内容都按原样存储并按原样显示(mysql charset 和排序规则设置为 utf8mb4...)。
更新 2
SELECT name, HEX(name) FROM person LIMIT 1
这是它的输出:
New Person has name Altaïr 416C7461C3AF72
但正如我已经说过的,这是使用:
$mysqli->set_charset('utf8');
插入和选择。如果我使用 utf8mb4 来代替它存储的内容:
Altaïr
但显示正常。不显示的问题是,如果名称按原样存储,则显示的名称将为Alta�r。
所以问题是:为什么mysqli/mysql 使用utf8mb4 将ï 存储为ï?为什么在mysqli中设置utf8mb4时,php会显示ï等特殊字符为�?
有人可以确认mysqli::set_charset 接受 utf8mb4 作为有效编码吗?
更新 3
我有一个从表“es”中选择字符串的类函数,例如:Iniciar Sesión(这是存储的)如果 mysqli charset 是 utf8,则选择/显示的是 Iniciar Sesión。
这可能是一个完全不同的问题,但它显然是另一个编码问题。据我了解,如果表/列是 utf8mb4 并且 mysqli 设置为 utf8,则 mysql 必须从 utf8(3 字节)编码为 ut8mb4(全字节支持)。所以这意味着mysqli 不使用 php 中的 utf8,而是使用 mysql 中的 utf8。这是正确的,对吧?
我的应用程序目前在编码方面遇到了困难...(但可能是一些服务器配置问题...)
更新 4
问题可能出在这里吗?我真的不知道这种配置:
SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
+--------------------------+--------------------+
| Variable_name | Value |
+--------------------------+--------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| collation_connection | utf8_general_ci |
| collation_database | utf8mb4_unicode_ci |
| collation_server | latin1_swedish_ci |
+--------------------------+--------------------+
10 rows in set (0.00 sec)
UPDATE 4-1/2(从评论中复制)
CREATE TABLE `es` (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
text varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY name (name)
) ENGINE=InnoDB AUTO_INCREMENT=76 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`
【问题讨论】:
-
没有转换?你是说BLOB?处理 UTF8 的经验法则是:始终记录转换 + 编码 + 解码的方法。
-
什么是 BLOB?我以为php为我处理了...如果php与utf8一起使用并从mysql中获取utf8mb4,需要什么样的转换?
-
BLOB 是一种 MySQL 数据类型,通常用于存储大量文本或二进制数据。见这里dev.mysql.com/doc/refman/5.7/en/blob.html。
-
对了。不,我不使用 BLOB,我只是使用基本数据类型如 text 和 var/char。
-
要检查的另一件事是您在列定义中为特殊字符分配了足够的空间。例如,
varchar(255)不够大,无法包含 255 个特殊字符。
标签: php mysql encoding utf-8 utf8mb4