我想当我需要通过mysqli向数据库插入超过max_allowed_packet
大小的BLOB时,我可以使用send_long_data
。这似乎适用于所有人(请参阅this或this或this)。这是一个(不)工作的最小例子:
<?php
# Establishing connection
$db = new mysqli('localhost', 'user', 'password', 'database');
$db->query('SET CHARACTER SET "utf8"');
# Get max value
$res = $db->query('SHOW VARIABLES WHERE `Variable_name` = "max_allowed_packet"');
$max = (int)$res->fetch_assoc()['Value'];
$res->free();
# Prepare
$content = file_get_contents('C:\\file.png');
$stmt = $db->prepare('UPDATE `table` SET `field` = ? WHERE `id` = ?');
$null = null;
$id = 1;
$stmt->bind_param('bi', $null, $id);
# send_long_data
$m = $max -8;
$p = -$m;
$l = strlen($content) + $p;
while($p < $l)
$stmt->send_long_data(0, substr($content, $p += $m, $m));
if(!$stmt->execute())
echo "{$db->errno}: {$db->error}";
# finalize
$stmt->close();
$db->close();
?>
如果包装尺寸小于max_packet_size
,则效果非常好。如果没有,有几个问题:
$m
设置为$max
,则无效。错误消息为2006: MySQL server has gone away
;在此之前,会发出警告:Warning: Error while sending STMT_SEND_LONG_DATA packet. ... on line 20
(20为$stmt->send_long_data
)max_packet_size
中减去至少8的值。为什么8?它取决于某些东西吗?为什么不简单max_packet_size
?1105: Parameter of prepared statement which is set through mysql_send_long_data() is longer than 'max_allowed_packet' bytes
substr
肯定会返回字节数,为mbstring.func_overload = 0
。send_long_data
的目的恰恰是为了传输超过max_packet_size
个字节!mysql_send_long_data
而不是mysqli_send_long_data
的内容?LONGBLOB
,并且能够保存数据。如果我增加max_packet_size
,一切正常。但我不能依赖于访问服务器变量的操作。如何传输超过max_packet_size
字节的内容?
答案 0 :(得分:0)
根本无法绕过max_packet_size(不修改它)。
请参阅MySQL文档: http://dev.mysql.com/doc/refman/5.5/en/packet-too-large.html
客户端和服务器都有自己的max_allowed_packet 变量,所以如果你想处理大数据包,你必须增加它 在客户端和服务器中都是变量。
答案 1 :(得分:0)
你需要像这样修改它:
SET GLOBAL max_allowed_packet = 32 * 1048576; // 32 MB
我认为PHP会缓存send_long_data()
发送的块,然后尝试一次性发送数据包。所以分块或发送一个警示,send_long_data()
仍取决于@@max_allowed_packet
MySQL变量定义的大小。
其中,恕我直言,这太奇怪了。