Хобрук: Ваш путь к мастерству в программировании

Отображение изображения, сохраненного как двоичное, в столбце Postgre bytea

Я застрял часами, работая над этим. В сети найдено несколько решений, но мне никто не помогает. У меня возникла проблема с отображением изображения в браузере с помощью 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);
    }
}

Я ценю некоторые объяснения по этому поводу, потому что я все еще в замешательстве после исследований и чтения.

22.10.2015

  • Вы можете выводить только одно изображение за раз и только бинарные данные изображения. 22.10.2015
  • @Musa Хорошо понял, это означает, что я могу поместить URL-адрес, вызывающий страницу для отображения изображения. Но перед этим мне нужно сначала успешно вывести изображение. 23.10.2015

Ответы:


1

Наконец я нашел способ сделать это. Основываясь на том, что я нашел в Обработка двоичных данных с помощью PDO поскольку я использую PDO для чтения столбца в БД.

Итак, я поместил эти две строки в свой цикл foreach:

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

И мой файл отображается красиво. Как указал @Musa, я могу печатать только одно изображение за раз, поэтому я собираюсь использовать img с src="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(). Надеюсь, это поможет людям. Спасибо.

23.10.2015
  • Если производительность имеет значение, я бы посоветовал вместо этого использовать PDO, а нативную PHP-библиотеку pgsql. 23.10.2015
  • @greg У меня есть PDO в классе БД, поэтому используется PDO. Теперь у меня проблема, так как header есть, я могу отображать только одно изображение. Как я указал выше, я могу получить доступ с внешней страницы, но мне нужно будет вызывать БД каждый раз, когда вызывается страница. Это непрактично, особенно для сайта с большим количеством изображений на одной странице. Я не могу передать binarydata, который является PHP Resource Id. Как мне быть с этим, есть идеи? 29.10.2015

  • 2

    Предполагая, что $product->binarydata имеет содержимое, полученное из столбца BYTEA, этот метод работает:

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

    за исключением случаев, когда несоответствие версии клиента/сервера упоминается в этом ответе, и в этом случае следует использовать формат escape для bytea.

    Код не должен выводить ничего, кроме двух строк выше.

    22.10.2015
  • Я прокомментировал echo части и поставил header('Content-type: image/png'); echo pg_unescape_bytea($product->binarydata); . Отображается только битое изображение. 23.10.2015
  • Новые материалы

    Получение стоковых обновлений с помощью Python
    Для начинающего финансового аналитика Введение Описание: Этот проект Python создает скрипт для получения текущих обновлений акций с финансового веб-сайта Yahoo. Для этого проекта мы..

    Это все, что вам нужно знать о Kotlin в 2022 году
    Добро пожаловать! Kotlin — это язык программирования, популярность которого, кажется, растет, его действительно можно использовать для создания чего угодно, и если вы хотите узнать о Kotlin,..

    Текстовый графический интерфейс с Lanterna на Java
    Мой опыт работы с компьютерами (и текстовыми графическими пользовательскими интерфейсами) начался еще в восьмидесятых, когда я был ребенком, на дне рождения друга. Это был «новенький» Amstrad..

    Перезарядите свой мозг: умопомрачительный потенциал мозговых компьютерных интерфейсов
    Способность читать свои мысли и управлять объектами разумом долгое время были предметом человеческого любопытства, ограниченного областью научной фантастики… то есть до сих пор? С технологией,..

    Основы C# — Нулевой оператор объединения (??)
    Оператор ?? называется null-coalescing operator . Этот оператор используется для предоставления значения по умолчанию, если значение операнда в левой части оператора равно null ...

    Сравнение номеров версий в C++ с использованием синтаксического анализа строк
    Номера версий обычно используются для обозначения развития или обновлений программного обеспечения или любого другого продукта. При работе с номерами версий в C++ может быть полезно сравнить две..

    В мир искусственного интеллекта…
    ИИ — это новое топливо в современном мире. Куда бы вы ни обратились, с кем бы вы ни разговаривали — они, как правило, упоминают об ИИ хотя бы раз в ходе разговора. ИИ гудит повсюду. У каждого..