Php 在PostgreSQL中存储类似BLOB的数据

Php 在PostgreSQL中存储类似BLOB的数据,php,postgresql,Php,Postgresql,我最近从MySQL切换到PostgreSQL。不过,我还有一个问题 以前,我会在MySQL中以BLOB格式存储小图像 PostgreSQL不知道什么是BLOB 我试着用BYTEA字段类型代替。我猜这实际上插入了一个大的(十六进制?)字符串,但现在我一直在尝试让这个字符串返回到用PHP显示实际图像 有什么想法吗?提前谢谢 下面是我用来将图像保存到数据库中的一段代码: $data = bin2hex(file_get_contents('php://input')); if (!empty($da

我最近从MySQL切换到PostgreSQL。不过,我还有一个问题

以前,我会在MySQL中以BLOB格式存储小图像

PostgreSQL不知道什么是BLOB

我试着用BYTEA字段类型代替。我猜这实际上插入了一个大的(十六进制?)字符串,但现在我一直在尝试让这个字符串返回到用PHP显示实际图像

有什么想法吗?提前谢谢

下面是我用来将图像保存到数据库中的一段代码:

$data = bin2hex(file_get_contents('php://input'));

if (!empty($data)) {
  $sql = "UPDATE asset SET data = X'%s' WHERE uuid = '%s'";
  $args = array($data, $asset_uuid);
}

psql(9.1.3)和PHP5.3.6被使用,而TEA是一个字节数组。这不是一种模式。见本规范第4.2.1.5节

输入bytea的正确方式是带有十六进制值的“\x…”。因此,您需要的是设置数据='\x%s'

您可能还希望查看准备好的语句

编辑:我可以通过以下方式将(文本)文件插入bytea:

$source = file_get_contents( 'hello.php' );
$insert = pg_prepare( $conn, '', 'insert into t (name, data) values($1,$2)' );
pg_execute( $conn, '', array( 'hello.php', $source ) );
第三次编辑:可以将文件插入数据库。然而,PHP中的pgsql驱动程序是非常不礼貌的。检索回实际数据的唯一方法是使用旧的bytea转义机制,如下所述:


我很抱歉这有多烦人。PHP中的PostgreSQL接口可以对二进制值进行一些重大修改。

Bytea是一个字节数组。这不是一种模式。见本规范第4.2.1.5节

输入bytea的正确方式是带有十六进制值的“\x…”。因此,您需要的是设置数据='\x%s'

您可能还希望查看准备好的语句

编辑:我可以通过以下方式将(文本)文件插入bytea:

$source = file_get_contents( 'hello.php' );
$insert = pg_prepare( $conn, '', 'insert into t (name, data) values($1,$2)' );
pg_execute( $conn, '', array( 'hello.php', $source ) );
第三次编辑:可以将文件插入数据库。然而,PHP中的pgsql驱动程序是非常不礼貌的。检索回实际数据的唯一方法是使用旧的bytea转义机制,如下所述:


我很抱歉这有多烦人。PHP中的PostgreSQL接口可以对二进制值进行一些重大修改。

要使用pg_*API插入bytea内容,二进制值应该始终通过
pg_escape_bytea()
函数运行,即使它被传递到
pg_execute
pg_query_params
函数。 这是因为pg_*层不“知道”特定参数具有二进制内容,而且它也不实现对参数类型的任何真正支持。因此,必须使用文本表示。它可以是
escape
形式,也可以是
hex
形式,对PG服务器来说并不重要,它与
bytea\u输出的值无关,这仅对从服务器读取的值有意义

例如:

$esc=pg_escape_bytea("\000\001\002");
pg_query_params('INSERT INTO some_table(some_col) VALUES($1)', array($esc));
  $p=pg_query("SELECT some_col FROM some_table WHERE...");
  $r=pg_fetch_array($p);
  $contents = pg_unescape_bytea($r[0]);

要使用pg_*API读取bytea内容,必须在获取后通过
pg_unescape\u bytea()
运行该值。假设客户端库不早于9.0(libq.so.5.3或更高版本),它可以对内容进行解码,无论是
hex
格式还是
escape
格式,它都会自动检测到内容。只有使用较旧的库时,才有必要强制
bytea\u输出
escape
,以便正确解码,可以使用
SET
动态解码,也可以静态解码整个数据库(
ALTER database SET bytea\u输出=escape
),或者在
postgresql.conf
中解码整个实例

例如:

$esc=pg_escape_bytea("\000\001\002");
pg_query_params('INSERT INTO some_table(some_col) VALUES($1)', array($esc));
  $p=pg_query("SELECT some_col FROM some_table WHERE...");
  $r=pg_fetch_array($p);
  $contents = pg_unescape_bytea($r[0]);

要使用pg_*API插入bytea内容,二进制值应始终通过
pg_escape_bytea()
函数运行,即使它被传递到
pg_execute
pg_query_params
函数。 这是因为pg_*层不“知道”特定参数具有二进制内容,而且它也不实现对参数类型的任何真正支持。因此,必须使用文本表示。它可以是
escape
形式,也可以是
hex
形式,对PG服务器来说并不重要,它与
bytea\u输出的值无关,这仅对从服务器读取的值有意义

例如:

$esc=pg_escape_bytea("\000\001\002");
pg_query_params('INSERT INTO some_table(some_col) VALUES($1)', array($esc));
  $p=pg_query("SELECT some_col FROM some_table WHERE...");
  $r=pg_fetch_array($p);
  $contents = pg_unescape_bytea($r[0]);

要使用pg_*API读取bytea内容,必须在获取后通过
pg_unescape\u bytea()
运行该值。假设客户端库不早于9.0(libq.so.5.3或更高版本),它可以对内容进行解码,无论是
hex
格式还是
escape
格式,它都会自动检测到内容。只有使用较旧的库时,才有必要强制
bytea\u输出
escape
,以便正确解码,可以使用
SET
动态解码,也可以静态解码整个数据库(
ALTER database SET bytea\u输出=escape
),或者在
postgresql.conf
中解码整个实例

例如:

$esc=pg_escape_bytea("\000\001\002");
pg_query_params('INSERT INTO some_table(some_col) VALUES($1)', array($esc));
  $p=pg_query("SELECT some_col FROM some_table WHERE...");
  $r=pg_fetch_array($p);
  $contents = pg_unescape_bytea($r[0]);

这两个答案都给了我一些想法,但没有一个是100%的答案

因此,我将在这个答案中解释我是如何让它工作的

在显示图像时,我使用了以下方法:

header('Content-Type: image/jpeg');

$data = pack("H*", pg_unescape_bytea($data));

echo $data;
$data = pg_escape_bytea($data); // Escape input for PostgreSQL
$sql  = "UPDATE asset SET data = '%s'WHERE uuid = '%s'";
我运行的是PHP5.3.8,在PHP5.4.0中,可以使用hex2bin而不是pack

将图像添加到数据库时,我使用了以下方法:

header('Content-Type: image/jpeg');

$data = pack("H*", pg_unescape_bytea($data));

echo $data;
$data = pg_escape_bytea($data); // Escape input for PostgreSQL
$sql  = "UPDATE asset SET data = '%s'WHERE uuid = '%s'";

我很高兴它现在起作用了。谢谢丹尼尔和约翰

这两个答案都给了我一些想法,但都不是100%的答案

因此,我将在这个答案中解释我是如何让它工作的

在显示图像时,我使用了以下方法:

header('Content-Type: image/jpeg');

$data = pack("H*", pg_unescape_bytea($data));

echo $data;
$data = pg_escape_bytea($data); // Escape input for PostgreSQL
$sql  = "UPDATE asset SET data = '%s'WHERE uuid = '%s'";
我运行的是PHP5.3.8,在PHP5.4.0中,可以使用hex2bin而不是pack

将图像添加到数据库时,我使用了以下方法:

header('Content-Type: image/jpeg');

$data = pack("H*", pg_unescape_bytea($data));

echo $data;
$data = pg_escape_bytea($data); // Escape input for PostgreSQL
$sql  = "UPDATE asset SET data = '%s'WHERE uuid = '%s'";

我很高兴它现在起作用了。谢谢丹尼尔和约翰

有代码示例吗?你试过什么?我试过通过打印字符串并使用正确的MIME类型头输出它。。。不起作用。@edwardmp:当你存储它时,你正在执行
bin2hex
。在回显之前,请尝试使用hex2bin
。hex2bin函数在PHP5中不存在。但我明白你的意思,我会尝试类似的方法