- 论坛徽章:
- 0
|
想用bytea类似存储图片,结果却失败了。在网上查了许多资料,但最后测试都失败。
数据库很简单:- CREATE TABLE images
- (
- id serial;
- data bytea;
- enc varchar;
- );
复制代码 这个是我前面在MySQL中测试BLOB的一个数据库,当然类型在MySQL中用的是MEDIUMBLOB。
最开始遇到的问题是直接插报错,加上- $db->exec("SET client_encoding = 'Latin1';");
复制代码 后可以了,但读的地方得到的数据无法使用,用strlen()也会报错(PHP的strlen是可以处理binary
string的,前面我在测试MySQL时用过)。
后来看PHP手册中说插入之前需要用pg_escape_bytea()转换,读取之后再用pg_unescape_bytea()
转换回来,但测试还是不行。
在插入之间读取escape之后的长度,和读出来的数据库是完全不同的,并且读出来之后unesacpe
后长度和原来是一样的。用一个文本文件测试了一下,发现escape之后只替换了少数字符,略增长
一些;但读出来之后就完成不一样了,是形如:- x7b23212f7573722f62696e2f656e762070797......
复制代码 的一串数据。似乎还需要做个什么转换,但查了半天也都只提到上述两个转换。
我怕是PDO和PostgreSQL的binary操作不兼容,特地用PHP中的pg_xxx测试了一下,结果更奇怪,
读取的地方unesacpe之后和原来长度是一样的,但直接从库中读到的data字段比它长度大1。
代码很简单:- $sql = $db->prepare("INSERT INTO images(data, enc) VALUES(?, ?)");
- $data_escaped = pg_escape_bytea($data);
- $ret = $sql->execute(array($data_escaped, $enc));
复制代码 $data是前面通过POST传上来的文件数据,这部分没什么问题,前面使用MySQL时是测试过的。
查询的地方:- $sql = $db->prepare("SELECT * FROM images WHERE id = ?");
- $ret = $sql->execute(array($image_id));
- $sql->bindColumn("id", $id);
- $sql->bindColumn("data", $data);
- $sql->bindColumn("enc", $enc);
- $sql->fetch(PDO::FETCH_BOUND);
- $data_escaped = pg_unescape_bytea($data);
复制代码 另外我有一个疑问,binary数据通常相对是比较大的数据,PostgreSQL如果对于binary数据一定要
escape一下不是运行效率和存储效率都比较低?在上述表中,enc是我用来测试base64编码的,在
测试时发现104642字节大小的图片,base64编码之后是139524,而pg_escape之后是316581,
从这个上说还不如用base64转换的效率。
同一个图片,插入到bytea之后,读出来的长度是209937。我怀疑应该是个低级错误
导致的,但从网上查来查去就是找不出原因在哪了
|
|