MySQL 保存 4 字节字符问题
今天在保存内容到数据库的时候报如下错误:
Incorrect string value: '\xF0\xA2\xB9\x82\xE5\xB8...' for column 'content' at row 1
本来还以为是多出来非法字符或者字符编码的问题,但试过了都不是,而 \xF0\xA2\xB9\x82\xE5\xB8
这些都是由字符转为 16 进制得出来的,最后还是谷歌找到了问题原因,还是编码的原因,只不过是 MySQL 的编码。
一般来说,正常汉字不会超过 3 个字节,但内容由于是繁体字,总会出现一些生僻字为 4 个字节 (当然,有的 emoji 表情符号也是 4 个字节),而 MySQL 的 UTF-8 编码只能支持 1-3 个字节,如果想保存 4 个字节的字符,则需要把字符集修改为 utf8mb4,而且 MySQL 的版本要高于 5.5.3。
根据前面 4 个字节 \xF0\xA2\xB9\x82
,可以得到一个不常见的繁体字,可以到这个网站进行转换。
修改字符集:
ALTER DATABASE `database_name` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
ALTER TABLE `table_name` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `table_name` CHANGE `column_name` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
注意,也要修改数据库连接所选择的字符集为 utf8mb4,例如 Yii:
return [
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=yii2',
'username' => 'root',
'password' => '',
'charset' => 'utf8mb4',
'tablePrefix' => 'yii2_',
],
],
];
2017-11-10
今天在尝试导出内容到 Excel 也是出现 4 字节字符识别不了的情况,打开文件后提示说识别不了某些字符,导致该字符后面所有行的数据大多数单元格为空。
处理方法有两种,但并不完美。
第一种是把 4 字节的字符去掉或者用空格代替,对于字符不多的内容倒无所谓,但是字符多或者不允许丢失内容的话,这种方法就不好了。
// 去除 4 字节字符
$newContent = preg_replace('/[\xF0-\xF7].../s', ' ', $content);
第二种是把导出格式更换为 Excel2007(xlsx),但是我打开导出的文件却弹出错误提示 Calculation is incomplete,不知道是不是个例,如果是个例的话这应该是比较好的方法了,参考下面有 PHPExcel 导出 xlsx 的例子。
参考
Incorrect string value: \xF0\x9F\x98\x84\xF0\x9F