在 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 指出的那样,我一次只能打印一张图像,所以我将使用 imgsrc="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() 配对使用。希望这可以帮助那里的人。谢谢。