1

我最近从 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) 和 php 5.3.6

4

3 回答 3

3

Bytea 是一个字节数组。这不是一点模式。请参阅PostgreSQL Lexical Structure的第 4.2.1.5 节。

输入 bytea 的正确方法是使用十六进制值的 '\x...'。所以你想要的是 SET data = '\x%s'。

您可能还想使用pg_prepare查看准备好的语句。

编辑:我能够将(文本)文件插入到 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 转义机制,详见此处:pg_unescape_bytea

pg_query('SET bytea_output = "escape";');

$result = pg_query( 'select data from t' );

while ( $row = pg_fetch_row( $result ) ) {
    echo pg_unescape_bytea( $row[0] );
}

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

于 2012-06-22T20:06:12.727 回答
3

要使用 pg_* API插入 bytea 内容,二进制值应始终通过pg_escape_bytea()函数运行,即使它已传递给pg_executeorpg_query_params函数。这是因为 pg_* 层不“知道”特定参数具有二进制内容,并且无论如何它都没有实现对参数类型的任何真正支持。所以必须使用文本表示。可以是escapeform hex,也可以是form,与PG服务器无关,与 的值无关,bytea_output仅对从服务器读取的值有意义。

例子:

$esc=pg_escape_bytea("\000\001\002");
pg_query_params('INSERT INTO some_table(some_col) VALUES($1)', array($esc));

要使用 pg_* API读取 bytea 内容,必须pg_unescape_bytea()在 fetch 之后运行该值。假设客户端库不早于 9.0(libq.so.5.3 或更高版本),它可以解码hex形式或escape形式的内容,并且会自动检测它。只有使用较旧的库才需要强制bytea_outputescape正确解码,无论是动态地SET还是静态地用于整个数据库(ALTER DATABASE SET bytea_output=escape)或postgresql.conf整个实例。

例子:

  $p=pg_query("SELECT some_col FROM some_table WHERE...");
  $r=pg_fetch_array($p);
  $contents = pg_unescape_bytea($r[0]);
于 2012-06-25T14:01:56.807 回答
3

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

因此,我将在此答案中解释我为使其正常工作所做的工作。

显示图像时,我使用了这个:

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

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

echo $data;

我正在运行 PHP 5.3.8,在 PHP 5.4.0 中你可以使用 hex2bin 而不是 pack。

将图像添加到数据库时,我使用了这个:

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

我很高兴它现在正在工作。谢谢丹尼尔和约翰!

于 2012-06-26T22:10:57.633 回答