在 Postgre bytea 列中显示存储为二进制的图像
Displaying Image Stored as Binary in Postgre bytea Column
我为此工作了好几个小时。在网上找到的解决方案很少,但似乎没有人帮助我。我在使用 PHP 在浏览器上显示图像时遇到问题,该图像从具有列类型 bytea 的 Postgres DB 获取图像。我确定我在这里遗漏了一些东西。所以非常感谢一些指导。所以我有下面的代码:
$prod = new Product();
$prod->display_latest_product();
if( $prod->exists() ){
$products = $prod->data();
foreach($products as $product){
echo $product->id;
echo $product->binarydata;
/* Solution below: I only get one image with broken link */
header('Content-type: image/png');
echo pg_unescape_bytea($product->binarydata);
/* Solution below: I only get one image with broken link */
header('Content-Type: image/png');
$data=fgets($product->binarydata);
print(pack('H*',$data));
/* bin2hex() expects parameter to be string but resource given */
echo bin2hex($product->binarydata);
/* Solution below: I only get one image with broken link */
$image = stripcslashes($product->binarydata);
header("Content-Type: image/png");
print($image);
}
}
我很感激对此的一些解释,因为经过研究和阅读后我仍然感到困惑。
假设 $product->binarydata
具有从 BYTEA
列中提取的内容,此方法有效:
header('Content-type: image/png');
echo pg_unescape_bytea($product->binarydata);
除非 this answer 中提到的 client/server 版本不匹配,在这种情况下,应使用 bytea 的 escape
格式。
除了以上两行,代码不能输出任何其他内容。
终于找到方法了。基于我在 Handling Binary Data with PDO 中发现的内容,因为我正在使用 PDO 读取数据库中的列。
所以我将这两行放在 foreach
循环中:
header("Content-Type: ".$product->mimetype);
fpassthru($product->binarydata);
而且我的文件显示得很好。正如@Musa 指出的那样,我一次只能打印一张图像,所以我将使用 img
和 src="thepage.php?img=xx"
来显示图像。我正在开发电子商务应用程序,所以不确定这是否会影响性能,因为将加载大量图像。欢迎任何意见或建议。无论如何,我希望这可以帮助那些遇到同样问题的人。
关于 fpassthru
的文档是 here.
编辑::找到解决方案
所以我终于找到了解决我在下面评论中定义的问题的真正解决方案。而这次完全不涉及PHP header
foreach($products as $product){
ob_start(); // Let's start output buffering.
fpassthru($binarydata); //This will normally output the image, but because of ob_start(), it won't.
$contents = ob_get_contents(); //Instead, output above is saved to $contents
ob_end_clean(); //End the output buffer.
$dataUri = "data:image/png;base64," . base64_encode($contents);
echo "<img src='$dataUri' />";
}
我找到了解决方案 here。根据该线程中的评论,诀窍实际上在于缓冲。 ob_start
必须与 ob_end_clean()
配对使用。希望这可以帮助那里的人。谢谢。
我为此工作了好几个小时。在网上找到的解决方案很少,但似乎没有人帮助我。我在使用 PHP 在浏览器上显示图像时遇到问题,该图像从具有列类型 bytea 的 Postgres DB 获取图像。我确定我在这里遗漏了一些东西。所以非常感谢一些指导。所以我有下面的代码:
$prod = new Product();
$prod->display_latest_product();
if( $prod->exists() ){
$products = $prod->data();
foreach($products as $product){
echo $product->id;
echo $product->binarydata;
/* Solution below: I only get one image with broken link */
header('Content-type: image/png');
echo pg_unescape_bytea($product->binarydata);
/* Solution below: I only get one image with broken link */
header('Content-Type: image/png');
$data=fgets($product->binarydata);
print(pack('H*',$data));
/* bin2hex() expects parameter to be string but resource given */
echo bin2hex($product->binarydata);
/* Solution below: I only get one image with broken link */
$image = stripcslashes($product->binarydata);
header("Content-Type: image/png");
print($image);
}
}
我很感激对此的一些解释,因为经过研究和阅读后我仍然感到困惑。
假设 $product->binarydata
具有从 BYTEA
列中提取的内容,此方法有效:
header('Content-type: image/png');
echo pg_unescape_bytea($product->binarydata);
除非 this answer 中提到的 client/server 版本不匹配,在这种情况下,应使用 bytea 的 escape
格式。
除了以上两行,代码不能输出任何其他内容。
终于找到方法了。基于我在 Handling Binary Data with PDO 中发现的内容,因为我正在使用 PDO 读取数据库中的列。
所以我将这两行放在 foreach
循环中:
header("Content-Type: ".$product->mimetype);
fpassthru($product->binarydata);
而且我的文件显示得很好。正如@Musa 指出的那样,我一次只能打印一张图像,所以我将使用 img
和 src="thepage.php?img=xx"
来显示图像。我正在开发电子商务应用程序,所以不确定这是否会影响性能,因为将加载大量图像。欢迎任何意见或建议。无论如何,我希望这可以帮助那些遇到同样问题的人。
关于 fpassthru
的文档是 here.
编辑::找到解决方案
所以我终于找到了解决我在下面评论中定义的问题的真正解决方案。而这次完全不涉及PHP header
foreach($products as $product){
ob_start(); // Let's start output buffering.
fpassthru($binarydata); //This will normally output the image, but because of ob_start(), it won't.
$contents = ob_get_contents(); //Instead, output above is saved to $contents
ob_end_clean(); //End the output buffer.
$dataUri = "data:image/png;base64," . base64_encode($contents);
echo "<img src='$dataUri' />";
}
我找到了解决方案 here。根据该线程中的评论,诀窍实际上在于缓冲。 ob_start
必须与 ob_end_clean()
配对使用。希望这可以帮助那里的人。谢谢。