MySQL / PDO截断数据

时间:2012-07-25 08:12:43

标签: mysql pdo mysqlnd

$book是一个7kb的字符串。如果使用PHP PDO exec执行此查询,则monograph列(LONGTEXT)数据将被截断为6765字符:

echo strlen($book); // output 7157

$db->exec("UPDATE `chemicals` SET `monograph` = {$db->quote($book)} WHERE `id` = {$db->quote($c['id'])};");

但是,如果我打印查询并使用SQL客户端(绕过PHP)执行它,它会将所有数据插入到数据库中。这让我觉得PHP设置我还不熟悉。

请注意,如果我使用预准备语句(包括PDO :: PARAM_LOB),也会发生同样的情况。

$book https://gist.github.com/79d5fe1050bbb0e2fac8之前转储

exec值(7157)。最终在数据库https://gist.github.com/df49d4a9707660b8b60b(6765)处的实际数据。我不明白这样的数据截断在技术上是如何可能的,因为整个查询被传递给MySQL(否则会弹出SQL语法错误)。

echo "UPDATE `chemicals` SET `monograph` = {$db->quote($book)} WHERE `id` = {$db->quote($c['id'])};";

如果我使用SQL客户端执行输出(https://gist.github.com/a05fe4c033e74897b82b),这是最终在数据库https://gist.github.com/88870fe26a3ae40e991e中的数据(7157,预期)。

使用UTF8连接启动PDO。

new PDO('mysql:dbname=[..];host=localhost;charset=utf8', 'root', '[..]', array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8' COLLATE 'utf8_unicode_ci';"));

更新2012年07月25日04:11 EST

现在我知道了编码问题。

$db->exec("UPDATE `chemicals` SET `monograph` = {$db->quote(utf8_decode($book))} WHERE `id` = {$db->quote($c['id'])};");

但是,我不知道该怎么办。我与MySQL的连接已经是unicode了。

/etc/my.cnf配置为在服务器范围内使用以下设置。

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci

2 个答案:

答案 0 :(得分:1)

这里有两点要做。一个是理想情况下所有字符编码必须是UTF8 - 即服务器,客户端,连接和表。第二,PHP的strlen函数计算字节数,而不是字符数。

您的表格字符集可能未设置为UTF8。你可以做到

SHOW CREATE TABLE chemicals;

检查一下。您还应将这些内容添加到my.cnf

[mysqld]
character-set-client=utf8
character-set-results=utf8

在此处阅读有关MySQL字符集的更多信息:

MySQL character sets

答案 1 :(得分:0)

原来它是编码问题。这是两个解决方案。最明显的是修复编码以匹配数据库/连接设置。在我的例子中,我得到一个iso-8859-1字符串并将其解释为unicode。

然而,无论如何,它不应该是一个问题。我进一步发现默认情况下PDO::ATTR_EMULATE_PREPARES设置为TRUE。