当我将某些字符保存到 MariaDB 数据库时,它们被存储为 2-4 个字符的字符串。
例如,™
在数据库中保存为 ™
。
来自包含我的表单的 html 页面的 head
<meta charset="utf-8">
当我检查发送到服务器的 header 时,它显示
Content-Type:text/html; charset=UTF-8
处理表单数据的 PHP 文件有
$mysqli->set_charset('utf8');
我已将数据库和表转换为 UTF8,方法是:
ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE tablename CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
检查information_schema表中的数据库和表详细信息,我可以看到数据库和表字符集是UTF8
,默认排序规则名称是utf8_general_ci
>.
但是错误编码的字符仍然被保存到数据库中。
我正在使用终端查看表数据,因此查看端的编码应该没有问题。
我还缺少什么?
==编辑==
回应@rick的评论 -
显示创建表search_templates;
:
search_templates | CREATE TABLE `search_templates` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`modified` timestamp NULL DEFAULT NULL,
`template` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`space` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`url` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`secure` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
和从 search_templates WHERE id = 25 中选择标题,十六进制(标题);
:
+-----------------------+--------------------------------------------+
| title | HEX(title) |
+-----------------------+--------------------------------------------+
| Kiddicare abc â„¢ | 4B69646469636172652061626320C3A2E2809EC2A2 |
+-----------------------+--------------------------------------------+
当通过十六进制到文本转换器时,它显示:Kiddicare abc Ⅲ
。
所以这些字符被这样保存到数据库中,这是否使问题变得更清楚?
==编辑==
根据@rick的建议(使用新添加的数据,因为之前的标题列已被删除):
SELECT title, CONVERT(BINARY(CONVERT( CONVERT(UNHEX(title) USING utf8) USING latin1)) USING utf8) FROM search_templates LIMIT 3;
->
+--------------------------------------------------------------------------------+-------------------------------------------------------------------------------------+
| title | CONVERT(BINARY(CONVERT( CONVERT(UNHEX(title) USING utf8) USING latin1)) USING utf8) |
+--------------------------------------------------------------------------------+-------------------------------------------------------------------------------------+
| Kids' Games & Toys » Toy Shop » Toys R Us | NULL |
| Kiddicare - Pushchairs | Prams | Car Seats | Baby Equipment | Online Baby Shop | NULL |
| Kiddicare â„¢ | NULL |
+--------------------------------------------------------------------------------+-------------------------------------------------------------------------------------+
最佳答案
CONVERT(BINARY(CONVERT(
CONVERT(UNHEX('C3A2E2809EC2A2') USING utf8)
USING latin1)) USING utf8) ==> '™'
该字符串末尾有一个“双重编码”商标。
这是重复的
Updating data in MySQL database after inserting in the wrong encoding
编辑
在上下文中,避免使用最里面的UNHEX
;做
CONVERT(BINARY(CONVERT(
CONVERT(title USING utf8)
USING latin1)) USING utf8)
示例
CONVERT(BINARY(CONVERT(
CONVERT('Kiddicare â„¢' USING utf8)
USING latin1)) USING utf8)
--> Kiddicare ™
但是,如果您可以重新加载数据并且数据是 utf8 编码的(看起来不是),那么始终使用 utf8 就是“正确的解决方案”。
关于mysql - 尽管字符集和发送的数据采用 UTF8 格式,数据库仍保存奇怪的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31123649/