在PostgreSQL bytea列中存储图像并显示为二进制的问题

4

我在这个问题上卡了好几个小时。在网上找到了一些解决方案,但似乎没有一个能帮助我。我使用PHP从Postgres数据库中获取类型为bytea的列中的图像,在浏览器上显示图像时出现了问题。我确定我在这里漏掉了一些东西。所以非常感谢任何指导。下面是我的代码:

$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);
    }
}

我希望您能给我一些解释,因为我在研究和阅读后仍然感到困惑。


您一次只能输出一张图片,并且只能输出二进制图像数据。 - Musa
@Musa 好的,我明白了,这意味着我可以放置调用页面以显示图像的URL。但在此之前,我需要先成功输出图像。 - UserProg
2个回答

1

最终我找到了解决方法。基于我在使用PDO处理二进制数据中找到的内容,因为我正在使用PDO读取数据库中的列。

所以我在我的foreach循环中添加了这两行代码:

header("Content-Type: ".$product->mimetype);
fpassthru($product->binarydata);

我的文件显示得很好。正如@Musa指出的那样,我一次只能打印一张图片,所以我将使用imgsrc="thepage.php?img=xx"来显示图片。我正在开发电子商务应用程序,因此不确定这是否会影响性能,因为将加载大量图像。欢迎任何意见或建议。无论如何,我希望这可以帮助那些遇到同样问题的人。
有关fpassthru的文档在这里。 编辑::找到解决方案 所以我终于找到了真正解决我的问题的解决方案,它不涉及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' />";
}

我已经在这里找到了解决方案。根据该线程中的评论,诀窍实际上是在缓冲区上的。 ob_start 必须与 ob_end_clean() 成对使用。希望这对那些需要帮助的人有所帮助。谢谢。


如果性能很重要,我建议不要使用PDO,而是使用本地PHP的pgsql库。 - greg
@greg 我在DB类中使用了PDO,这就是为什么要使用PDO的原因。现在遇到问题了,因为有了“header”,我只能显示一张图片。正如我上面指出的那样,我可以从外部页面获取,但每次调用页面都需要调用DB,这对于一个页面有很多图片的网站来说是不切实际的。我无法传递PHP“Resource Id”类型的“binarydata”。你有什么想法吗? - UserProg

0
假设$product->binarydata包含从BYTEA列中获取的内容,此方法可以正常工作:
    header('Content-type: image/png');
    echo pg_unescape_bytea($product->binarydata);

除非出现客户端/服务器版本不匹配的情况,如this answer所述,否则应使用escape格式来处理bytea。

代码不能输出除上述两行之外的任何内容。


我已经注释了 echo 部分并添加了 header('Content-type: image/png'); echo pg_unescape_bytea($product->binarydata);。只有损坏的图像显示出来。 - UserProg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接