0

这一定是常见问题,但我无法从谷歌找到。我们有一个表格,并且在 postgresql 中有一个 bytea 类型的照片列。我们正在使用此代码段保存即将发布的图像:

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

储蓄似乎运作良好。

这是我们从 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不是二进制字符串,它是作为资源而来的。知道如何使它工作吗?

提前致谢。

4

2 回答 2

3

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

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

如果您使用 PDO 而不是本机 PostgreSQL 驱动程序,请查看如何使用 PDO 处理 bytea。您实际上根本没有显示您的数据库代码,只是对其进行了一些包装,因此很难判断发生了什么。

当然,这一切只适用于 PHP;大多数语言都有单独的“文本数据”和“二进制数据”数据类型,让客户端库自动转换二进制数据,而无需跳过转义/转义钩子。

于 2013-06-09T08:27:41.657 回答
0

对我来说这个解决方案:

将文件保存到数据库:

$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;
于 2015-09-07T08:26:29.670 回答