用PHP显示PostgreSQL数据库中的图像



我想在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"图标。这里怎么了?我该如何解决这个问题?非常感谢。

简单处理:

<?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的逆。关于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服务器是否足够新(>=9.0)以支持字节字符串中的十六进制序列x...
  • standard_conforming_stringsonoff(>=9.1时默认为on)

不同配置中相同输入的不同结果示例:

服务器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:

\\0001

现在使用较旧的配置: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或类似的独立于服务器的固定可逆变换,因为它不是。

最新更新