PHP将图像保存到postgresql并读取它不工作


php saving an image to postgresql and read it back is not working

这一定是常见的问题,但我无法从谷歌找到。我们有一个表和照片列在bytea类型在postgresql。我们用下面的代码片段保存即将到来的图像:

$photo->attributes = $_FILES['Photo'];
$file = CUploadedFile::getInstance($photo, 'photo');
$path = Yii::app()->basePath . '/data/' . $file->name;
$file->saveAs($path); //save the file to the $path
$fp = fopen($path, 'rb');
$content = fread($fp, filesize($path));  //get the file content
fclose($fp);
$photo->photo = base64_encode($content);   //encode it
$photo->save();  //save the record to db
unlink(Yii::app()->basePath . '/data/' . $file->name);

saving似乎运行良好。

这是我们从db:

读取blob字段的地方
base64_decode($data->photo) //this call is giving base64_decode() expects parameter 1 to be string, resource given error. 

如果我这样做:

print_r($data->photo) //I am getting: Resource id #51

显然$data->photo不是二进制字符串,它是作为资源来的。知道怎么做吗?

提前感谢。

如果您使用base64,那么您不需要bytea,您可以使用常规text字段。这样会降低磁盘空间的效率,但仅此而已。

如果你想存储实际的字节,你不把它编码为base64,你使用pg_escape_bytea将其转换为PostgreSQL的十六进制字符串表示(对于现代PostgreSQL版本)的bytea值。在提取数据时使用pg_bytea_decode

如果您使用PDO而不是本地PostgreSQL驱动程序,请查看如何使用PDO与bytea一起工作。实际上你根本没有显示你的数据库代码,只有一些包装器,所以很难知道发生了什么。

当然,所有这些只适用于PHP;大多数语言都有"文本数据"answers"二进制数据"的独立数据类型,这使得客户端库可以自动转换二进制数据,而不必跳过escape/unescape钩子。

对于我的工作这个解决方案:

保存文件到DB:

$file = CUploadedFile::getInstanceByName('file');
if ($file!=null) {
    $fp = fopen($file->tempName,'r');
    $content = fread($fp,  $file->size);
    fclose($fp);
    $doc->doc=null;  //bytea field
    $doc->docname = $file->name;
    $doc->mime = $file->type;
    $doc->size = $file->size;
    $doc->save();   
    $msg = $doc->getErrors();
    $command = Yii::app()->db->createCommand('UPDATE '.
                $doc->tableName().' SET "doc"=:doc WHERE id='.$doc->id); 
    $command->bindParam(":doc", $content, PDO::PARAM_LOB); // <-- look this!
    $command->execute();
} 

显示数据库中的文件:

header('Content-Type: '.$doc->mime );
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename*=UTF-8''''' . rawurlencode ($doc->docname ) );
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . $doc->size);
$content = fread($doc->doc, $doc->size);
echo $content;
exit;