Показать изображение из базы данных PostgreSQL в PHP

Я хочу отобразить изображение из моей базы данных PostgreSQL в файле PHP. Пробовав множество разных возможностей, я не очень далеко. Вот что я делаю:

Загрузить:

echo "<div>". "<table border=\"1\" cellpadding=\"3\">". "<form action=\"test2.php\" method=\"post\" enctype=\"multipart/form-data\">". "<tr>". "<td>". "<input type=\"file\" name=\"file\" id=\"file\">". "<input class=\"button\" type=\"submit\" name=\"submit\" value=\"Submit\">". "<tr>". "</tr>". "</form>". "</table>". "</div>"; 

Дисплей:

 if(isset($_FILES['file'])) //file uploaded { $file_raw = file_get_contents($_FILES['file']['tmp_name']); $file = pg_escape_bytea($file_raw); //Here is Code to insert into Database but just to test, I try it directly: header('Content-Type: image/png'); echo pg_unescape_bytea($file); } 

У меня уже есть часть отображения в дополнительном файле и так далее, но это важная информация, которую вам нужно знать.

Я не получу отображаемое изображение, просто значок «Сломанное изображение» из браузера. Что здесь не так? Как я могу это решить? Спасибо!

Простое управление:

 <?php // Connect to the database $dbconn = pg_connect( 'dbname=foo' ); // Read in a binary file $data = file_get_contents( 'image1.jpg' ); // Escape the binary data to avoid problems with encoding $escaped = bin2hex( $data ); // Insert it into the database pg_query( "INSERT INTO gallery (name, data) VALUES ('Pine trees', decode('{$escaped}' , 'hex'))" ); // Get the bytea data $res = pg_query("SELECT encode(data, 'base64') AS data FROM gallery WHERE name='Pine trees'"); $raw = pg_fetch_result($res, 'data'); // Convert to binary and send to the browser header('Content-type: image/jpeg'); echo base64_decode($raw); ?> 

Короткий ответ заключается в том, что pg_unescape_bytea не обязательно является инверсией pg_escape_bytea . Об этом упоминается в документации libpq о PQunescapeBytea :

Это преобразование не является точно обратным к PQescapeBytea, потому что строка не будет «экранирована», если она получена из PQgetvalue

Вернемся к php, вам нужно будет сделать обратный путь через базу данных, чтобы тест имел смысл, например:

 $pgconn = pg_connect("...."); $escaped = pg_escape_bytea($pgconn, $bytes); $pgr = pg_query($pgconn, "SELECT '$escaped'::bytea"); list($textual) = pg_fetch_array($pgr); $raw_bytes = pg_unescape_bytea($textual); 

В этом случае $raw_bytes будет во всех случаях идентичным начальным $bytes .


На стороне примечания, если вы хотите копать глубже, это гораздо больше.

pg_escape_bytea использует ресурс подключения к базе данных в качестве необязательного аргумента:

 string pg_escape_bytea ([ resource $connection ], string $data ) 

Его поведение отличается от того, используется ли соединение или нет (когда $connection оставлено вне, но pg_connect() был вызван раньше, «текущее соединение» будет использоваться в любом случае).

Когда используется соединение, его вывод управляется свойствами соединения, а именно:

  • достаточно ли PG-сервер (> = 9.0) для поддержки шестнадцатеричных последовательностей \x... в байтовых строках?
  • является standard_conforming_strings для on или off (по умолчанию, когда> = 9.1)

Примеры различных результатов с одним и тем же входом в разных конфигурациях:

Сервер 9.1, клиент 9.1, php 5.3.10

Код №1:

 // No connection // pg_connect("dbname=test"); echo pg_escape_bytea(chr(0).chr(1)); 

Результат №1:

  \\ 000 \\ 001

Код №2:

 // With connection $pgconn= pg_connect("dbname=test"); echo pg_escape_bytea(chr(0).chr(1)); 

Результат №2:

  \ x0001

Код №3:

 // With connection $pgconn= pg_connect("dbname=test"); pg_query("SET standard_conforming_strings TO off"); echo pg_escape_bytea(chr(0).chr(1)); 

Результат №3:

  \\ x0001

Теперь с более старой конфигурацией: клиент 8.4, сервер 8.4, php 5.2.6 :

Код №4:

 $pgconn= pg_connect("dbname=test"); pg_query("SET standard_conforming_strings TO off"); echo pg_escape_bytea(chr(0).chr(1)); 

Результат №4:

  \\ 000 \\ 001

Код №5:

 $pgconn= pg_connect("dbname=test"); pg_query("SET standard_conforming_strings TO on"); echo pg_escape_bytea(chr(0).chr(1)); 

Результат №5:

  \ 000 \ 001

Теперь нам не нужно заботиться обо всем этом при нормальном использовании. Простое использование его по назначению с его подключением будет работать, поскольку сервер правильно интерпретирует результаты. Дело в том, чтобы не предполагать, что pg_escape_bytea является независимым от сервера фиксированным обратимым преобразованием, таким как bin2hex или некоторым таким, потому что это не так.