MySQL/PDO截断数据

Gaj*_*jus 5 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'])};");
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

PDO使用UTF8连接启动.

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

更新2012年07月25日04:11美国东部时间

现在我知道这是编码问题.

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

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

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

[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
Run Code Online (Sandbox Code Playgroud)

Gar*_*y G 1

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

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

SHOW CREATE TABLE chemicals;
Run Code Online (Sandbox Code Playgroud)

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

[mysqld]
character-set-client=utf8
character-set-results=utf8
Run Code Online (Sandbox Code Playgroud)

在这里阅读有关 MySQL 字符集的更多信息:

MySQL 字符集