Я хочу отобразить изображение из моей базы данных 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()
был вызван раньше, «текущее соединение» будет использоваться в любом случае).
Когда используется соединение, его вывод управляется свойствами соединения, а именно:
\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
или некоторым таким, потому что это не так.