使用PostgreSQL的bytea字段存读取文件及读取出错问题处理

摘要:
//$fileName是文件路径地址;这里我们处理$fileContents=file_get_contents($fileUrl),$escapeBytea=pg_eescape_bytea($fileContents);pg_Query($dbconn;在PHP中使用pg_unescape_byte方法从字节字段恢复文件?

  PostgreSQL中的bytea字段类型可以以二进制的形式存储数据,这样做的好处就是可以将原本存储在网站目录下的文件存储到数据库中,坏处就是如果文件过多、过大的话,就会导致数据库的数据量大大增加,备份和恢复的时候就会浪费大量的时间,而且数据也有可能会出错。个人觉得,在文件量小的情况下,使用这种存储方式还是很方便的。

  言归正传,下面介绍一下使用bytea字段存读取文件的具体实现方法。首先是文件存储于存储于bytea字段的方法,主要用到的就是PHP中的pg_escape_bytea方法,代码如下:

<?php
$dbconn = pg_connect("host='localhost' dbname='dbname' user='user' password='password' port='port'")
    OR DIE('Could not connect:' . pg_last_error());
$fileUrl = iconv("utf-8", "gbk", $fileUrl);//$fileName为文件路径地址,汉字可能会乱码,此处处理一下
$fileContents = file_get_contents($fileUrl);
$escapeBytea = pg_escape_bytea($fileContents);//转义bytea数据类型的二进制字符串
$insertStr = "INSERT INTO tableName(id, contents)
            VALUES(DEFAULT, '{$escapeBytea}')";
pg_query($dbconn, $insertStr);
?>

   从bytea字段中还原文件用到的是PHP中的pg_unescape_bytea方法,实现代码如下:

<?php
    $dbconn = pg_connect("host='localhost' dbname='dbname' user='user' password='password' port='port'")
                    OR DIE('Could not connect: ' . pg_last_error());
    $selectStr = "SELECT contents
                FROM tableName
                WHERE id = " . $fileId;//$fileId为文件id
    $query = pg_query($dbconn, $selectStr);
    while($row = pg_fetch_array($query, null, PGSQL_ASSOC)){
        $escapeBytea = $row['contents'];
        $fileContents = pg_unescape_bytea($escapeBytea); //获得二进制数据
        file_put_contents($fileName, $fileContents); //$fileName为带有后缀名的文件名,如hello.pdf
}
?>

   导出文件后,如果二进制数据转码错误就会出现文件打不开的现象,比如错误的PDF文件打开时弹出错误如下图:

使用PostgreSQL的bytea字段存读取文件及读取出错问题处理第1张

  这种错误在数据库迁移时特别容易出现(本人是从PostgreSQL 8.4迁移到9.1),解决的方法是修改PostgreSQL的配置文件
postgresql.conf,将bytea_output的输出类型设置为转义类型(escape)输出,即bytea_output = 'escape'(如果前面有#,删除开启配置),然后reload一下PostgreSQL的配置使修改生效,这样二进制数据就可以正常解码并输出到文件。  

免责声明:文章转载自《使用PostgreSQL的bytea字段存读取文件及读取出错问题处理》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Java 生成三位随机数python实现获取登录验证码图片下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python之数据类型详解

         python之数据类型详解 二.列表list  (可以存储多个值)(列表内数字不需要加引号) sort 1 s1=['a','b','zz','1','!'] 2 # s1.sort() 3 # print(s1) -->['!', '1', 'a', 'b', 'zz'] 列表排序,特殊字符不准,数字第一,字母第二,汉字第三 c...

js数组删除(splice和delete)

最近一直在写js的数组,然后就发现了很奇怪的问题,后来才发现了规律。 删除数据的一行,一般有两种方法,一个是splice,一个是delete; splice:删除了数组后,数组的长度会自动变化。用法:arr.splice(2,1)——2是数组的下标值,1 代表输出一行数据。 delete: 删除了数组后,数组的长度不会变化。 用法:delete arr[2...

ansible 基本使用-1

概述 ansible  当前主流的批量配置管理工具,相比于saltstack 它是无agent 模式,基于ssh 去远程管理主机。有密码和密钥两种方式远程认证方式。 安装 yum -y install  ansible  (前提是有epel 源,如果没有需要安装) pip install ansible github源码包安装 环境 服务端 python ...

Dump Lsass内存转储新旧方法

  之前看到一篇关于Lsass内存dump的文章,学习记录一下。   lsass.exe(Local Security Authority Subsystem Service)进程空间中,存有着机器的域、本地用户名和密码等重要信息。如果获取本地高权限,用户便可以访问 LSASS 进程内存,从而可以导出内部数据(password),用于横向移动和权限提升。...

php 安装教程

php 安装教程  本文采用php7.0.1作为样例,进行安装。 系统环境:   CentOS6.7.   gcc 4.8.2   libzip 1.0.1 在安装之前,可以先更新CentOS系统。 yum -y update 下载相应依赖文件 wget "http://cn2.php.net/distributions/...

Linux编译安装安Python3.7/3.8出现_ssl模块错误| python运行ssl模块出现ModuleNotFoundError

背景: 今天在Linux上使用paramiko模块的时候,出现了错误:ModuleNotFoundError:No module name '_ssl',但是我的系统是安装了openssl的1.0.1的,查了网络上的信息发现,Python3.7以后的版本,需要openssl1.0.2+,或者Libressl2.6.4+。 按照网络上的方法,安装了opens...