在PHP中显示来自PostgreSQL数据库的图像

时间:2014-03-05 22:19:33

标签: php postgresql png bytearray

我想在PHP文件中显示PostgreSQL数据库中的图像。 在尝试了很多不同的可能性后,我不会走得太远。 这是我的工作:

上载:

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);
}

我已将显示部分放在额外的文件中,依此类推,但这些是您需要了解的基本信息。

我不会显示任何图像,只是浏览器中的“Broken Image”图标。 这有什么不对?我怎么解决这个问题? 谢谢!

2 个答案:

答案 0 :(得分:5)

简单处理:

<?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);
?>

答案 1 :(得分:2)

简短的回答是pg_unescape_bytea不一定是pg_escape_bytea的倒数。关于PQunescapeBytea

的libpq文档中提到了这一点
  

这种转换与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服务器(&gt; = 9.0)以支持bytea字符串中的十六进制序列\x...
  • 默认为standard_conforming_stringsonoffon当&gt; = 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或其他一些,因为它不是。