Php 存储在MySQL中的二进制数据已损坏

Php 存储在MySQL中的二进制数据已损坏,php,mysql,sql,pdo,binary-data,Php,Mysql,Sql,Pdo,Binary Data,我需要在MySQL数据库中存储50 KiB-500 KiB二进制文件(实际上是zlib压缩文本文件)。假设有很好的理由这样做,而不是仅仅将它们写入文件系统,那么数据库中的数据就会被破坏。我用PHP和Python两种语言把它拉出来,它们都表明数据已经损坏 我曾经尝试过使用PHP模拟预处理语句和非模拟预处理语句来输入数据,并简单地将数据正确地放在查询中,就像它是一个字符串一样。所有这些都导致数据损坏 准备好的声明: $options = array('PDO::ATTR_EMULATE_PREPAR

我需要在MySQL数据库中存储50 KiB-500 KiB二进制文件(实际上是zlib压缩文本文件)。假设有很好的理由这样做,而不是仅仅将它们写入文件系统,那么数据库中的数据就会被破坏。我用PHP和Python两种语言把它拉出来,它们都表明数据已经损坏

我曾经尝试过使用PHP模拟预处理语句和非模拟预处理语句来输入数据,并简单地将数据正确地放在查询中,就像它是一个字符串一样。所有这些都导致数据损坏

准备好的声明:

$options = array('PDO::ATTR_EMULATE_PREPARES' => FALSE);
$dsn = 'mysql:host=localhost;dbname=qb_cache;charset=utf8';
$pdo = new PDO($dsn, 'root', 'hunter2', $options);

$sql = 'INSERT INTO cache (body) VALUES (:body)';
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':body', $body);
$dsn = 'mysql:host=localhost;dbname=qb_cache;charset=utf8';
$pdo = new PDO($dsn, 'root', 'hunter2');

$sql = 'INSERT INTO cache (body) VALUES (:body)';
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':body', $body);
通过模拟准备好的语句:

$options = array('PDO::ATTR_EMULATE_PREPARES' => FALSE);
$dsn = 'mysql:host=localhost;dbname=qb_cache;charset=utf8';
$pdo = new PDO($dsn, 'root', 'hunter2', $options);

$sql = 'INSERT INTO cache (body) VALUES (:body)';
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':body', $body);
$dsn = 'mysql:host=localhost;dbname=qb_cache;charset=utf8';
$pdo = new PDO($dsn, 'root', 'hunter2');

$sql = 'INSERT INTO cache (body) VALUES (:body)';
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':body', $body);
直接进入数据库:

$dsn = 'mysql:host=localhost;dbname=qb_cache;charset=utf8';
$pdo = new PDO($dsn, 'root', 'hunter2');

$sql = "INSERT INTO cache (body) VALUES ('{$body}')";
$stmt = $pdo->prepare($sql);
请注意,二进制数据没有PDO!顺便说一下,我不认为我达到了MySQL字段的大小限制:

mysql> show variables like 'max_allowed_packet';
+--------------------+----------+
| Variable_name      | Value    |
+--------------------+----------+
| max_allowed_packet | 16777216 |
+--------------------+----------+
1 row in set (0.00 sec)
这是我尝试解码时得到的结果:

$ zlib-flate -uncompress < output_from_database
...snip...
74 ARP4s0B64R9P6oZOpe6262E}C k3A AFD001 Si IL4A57sflate: inflate: data: invalid block type


$ cat output_from_database | openssl zlib -d > decoded
140438369359520:error:29065064:lib(41):BIO_ZLIB_READ:zlib inflate error:c_zlib.c:570:zlib error:data error
$zlib flate-从数据库解压缩已解码
140438369359520:错误:29065064:lib(41):BIO_ZLIB_读取:ZLIB充气错误:c_ZLIB.c:570:ZLIB错误:数据错误
使用Python从MySQL中提取数据,我发现字段大小合适,但无法解压缩:

>>> pprint(zlib.decompress(row[0]))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
zlib.error: Error -5 while decompressing data: incomplete or truncated stream
>pprint(zlib.decompress(行[0]))
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
zlib.error:解压缩数据时出错-5:流不完整或被截断

问题是列类型是
blob
,因为某种原因,我认为
blob
是MySQL支持的最大数据类型。事实证明,当我实际查看并看到数据库的大小是65535字节时,我知道数据被截断了转到
longblob
解决了问题。


对于下一个家伙:。

有。还有什么是列数据类型?@dev null居住者:谢谢,这是一个伟大的发现。列类型是
blob
,因为某种原因,我认为
blob
是MySQL支持的最大数据类型。事实证明,当我实际查看并看到数据库的大小是65535字节时,我知道数据被截断了。移动到
longblob
解决了这个问题。没有很好的理由这样做,而不是只将它们系统地写入文件,有时是这样的。1) 在云计算中,数据库自动跨地理区域复制,但没有带文件系统的“规范”服务器(不是我当前的应用程序,但我见过它们)。2) 对文件系统没有写权限(同样,现在不适用,但我已经看到了)。3) 简化或现有的备份和版本控制系统(同样,不是我目前的情况)。4) 分布式计算(与云计算一样,没有单一的规范文件系统)。5) 另一个原因,也就是我目前的处境:)@YourCommonSense:不是我对你的PDO答案投了反对票(实际上,我投了反对票),尽管我对一个争论点发表了评论。无论如何,即使你认为我已经否决了你的一篇帖子,“代表报复”也有点不酷。