【问题标题】:Displaying Image Stored as Binary in Postgre bytea Column在 Postgre bytea 列中显示以二进制形式存储的图像
【发布时间】:2015-10-22 10:08:05
【问题描述】:

我为此工作了好几个小时。在网上找到的解决方案很少,但似乎没有人能帮助我。我在使用 PHP 从 Postgres DB 中获取具有列类型 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 OK 明白了,也就是说我可以把调用页面的URL放上来显示图片。但在此之前,我需要先成功输出图像。

标签: php postgresql binary bytea


【解决方案1】:

我终于找到了方法。基于我在Handling Binary Data with PDO 中发现的内容,因为我正在使用 PDO 读取 DB 中的列。

所以我把这两行放在我的foreach 循环中:

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

我的文件显示得很好。正如@Musa 指出的,我一次只能打印一张图像,所以我将使用imgsrc="thepage.php?img=xx" 来显示图像。我正在开发电子商务应用程序,因此不确定这是否会影响性能,因为将加载大量图像。欢迎任何cmets或建议。无论如何,我希望这可以帮助那些遇到同样问题的人。

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() 配对使用。希望这可以帮助那里的人们。谢谢。

【讨论】:

  • 如果性能很重要,我建议不要使用 PDO,而是使用原生 PHP 的 pgsql 库。
  • @greg 我在 DB 类中有 PDO,所以这就是使用 PDO 的原因。现在有问题,因为header 在那里,我只能显示一张图像。正如我上面指出的,我可以从外部页面获取,但每次调用页面时都需要调用 DB。这是不切实际的,尤其是对于在一页中有很多图像的网站。我无法通过 binarydata,即 PHP Resource Id。我该怎么做,知道吗?
【解决方案2】:

假设$product-&gt;binarydata 具有从BYTEA 列获取的内容,则此方法确实有效:

    header('Content-type: image/png');
    echo pg_unescape_bytea($product->binarydata);

除非在this answer 中提到的客户端/服务器版本不匹配,在这种情况下应该使用 bytea 的escape 格式。

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

【讨论】:

  • 我已经评论了 echo 部分并输入了 header('Content-type: image/png'); echo pg_unescape_bytea($product-&gt;binarydata); 。仅显示损坏的图像。
猜你喜欢
  • 2016-09-01
  • 2021-10-29
  • 1970-01-01
  • 2012-01-07
  • 2021-11-27
  • 1970-01-01
  • 1970-01-01
  • 2018-07-31
相关资源
最近更新 更多