这一定是常见的问题,但我无法从谷歌找到。我们有一个表和照片列在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;