将UTF-8编码的字符串插入UTF-8编码的mysql表失败,并显示“字符串值不正确”

时间:2012-08-13 14:59:29

标签: php mysql drupal

将UTF-8编码的字符串插入UTF-8编码表会产生不正确的字符串值。

  

PDOException:SQLSTATE [HY000]:常规错误:1366字符串值不正确:'\ xF0 \ x9D \ x84 \ x8E i ...'第1行的列'body_value':INSERT INTO

我有一个字符,在mb_detect_encoding声称为UTF-8编码的字符串中。 我尝试将此字符串插入到MySQL表中,该表定义为(除其他外)DEFAULT CHARSET=utf8

编辑:Drupal始终SET NAMES utf8使用可选COLLATE(至少在与MySQL交谈时)。

编辑2 :一些看似相关的细节。我从PostgreSQL数据库中获取了一些文本。我将它粘贴到一个对象上,使用mb_detect_encoding验证它是UTF-8,并使用node_save将对象持久保存到数据库。因此,虽然有一个触发导入的HTTP请求,但数据并非来自浏览器。

编辑3:数据在两个表上非规范化:

  

SELECT character_set_name FROM information_schema。COLUMNS C WHERE table_schema =“[database]”AND table_name IN(“field_data_body”,“field_revision_body”)AND column_name =“body_value”;

>+--------------------+
| character_set_name |
+--------------------+
| utf8               |
| utf8               |
+--------------------+

编辑4:该字符是否可能“新建”?我对the relationship between unicode and UTF-8有点模糊,但这wikipedia article暗示这个角色最近已标准化。

我不明白“字符串值不正确”会如何失败。

4 个答案:

答案 0 :(得分:14)

(U + 1D10E)是在BMP(基本多语言平面)之外找到的字符Unicode(在U + FFFF之上),因此不能以3字节的UTF-8表示。 MySQL charset utf8只接受UTF-8字符,如果它们可以用3个字节表示。如果你需要在MySQL中存储它,你需要使用MySQL charset utf8mb4。你需要MySQL 5.5.3或更高版本。您可以使用ALTER TABLE来更改字符集而不会出现太多问题;因为它需要更多空间来存储字符,所以会出现一些问题,可能需要您减少字符串大小。请参阅http://dev.mysql.com/doc/refman/5.5/en/charset-unicode-upgrading.html

答案 1 :(得分:4)

要解决此问题,首先将数据库字段更改为utf8m4b charset。例如:

ALTER TABLE `tb_name` CHANGE `field_name` `field_name` VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL; 

然后在你的数据库连接中,将driver_options设置为utf8mb4。例如,如果您使用PDO

$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8mb4', 'username', 'password');

或在zend framework 1.2中

$dbParam = array('host' => 'localhost', 'username' => 'db_user_name',
            'password' => 'password', 'dbname' => 'db_name',
            'driver_options' => array(
                '1002' => "SET NAMES 'utf8mb4'",
                '12'    => 0
            )
        );

答案 2 :(得分:3)

在PDO连接中,设置字符集。

new PDO('mysql:host=localhost;dbname=the_db;charset=utf8mb4', $user, $password);

答案 3 :(得分:0)

我修复了错误: SQLSTATE [HY000]:常规错误:1366错误的字符串值...... 用这种方法:

我将utf8mb4_unicode_ci用于数据库 database 为所有表设置utf8mb4_unicode_ci tables

设置列的longblog数据类型(不是文本,longtext。...您需要大数据类型来存储4个字节的内容) fields

现在可以了。 如果您使用laravel,请继续编辑config / database.php

'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',

laravel

如果使用功能strtolower,则将其替换为mb_strtolower 注意:您必须将<meta charset="utf-8">放在头部标签上