Ola*_*ayo 7 php postgresql heroku bytea
我使用PHP将图像存储在具有列类型bytea的PostgreSQL数据库中.问题是每次我尝试在浏览器中加载图像时都不会出现.Firefox开发人员控制台表示图像被截断或损坏.
PHP代码:
//code for inserting into the database
if(array_key_exists('submit_pic', $_POST)){
$user=$_SESSION['name'];
if(isset($_FILES['thumbnail'])&&$_FILES['thumbnail']['size']>0){
$fi = $_FILES['thumbnail']['tmp_name'];
$p=fopen($fi,'r');
$data=fread($p,filesize($fi));
$data=addslashes($data);
$dat= pg_escape_bytea($data);
$q="update userinfo set image='{$dat}' where email='$user'";
$e=pg_query($q)or die(pg_last_error());
// code for retreving from database
require_once('conn.php');
session_start();
$user=$_SESSION['name'];
pg_query('SET bytea_output = "escape";');
$lquery ="select image from userinfo where email='$user'";
$lq = pg_query($lquery)or die(pg_last_error());
$lqq=pg_fetch_row($lq,'image');
header("conent-type:image");
echo pg_unescape_bytea($lqq[0]);
Run Code Online (Sandbox Code Playgroud)
我需要将上传的图像存储在数据库中 - 我实际上正在使用heroku谢谢
Cra*_*ger 13
删除addslashes($data).这里多余.
$data=fread($p,filesize($fi));
$data=addslashes($data);
$dat= pg_escape_bytea($data);
Run Code Online (Sandbox Code Playgroud)
您读取数据,将其转义为字符串文字,然后将其转换为bytea八进制或十六进制转义.它可能永远不会那样,即使pg_escape_bytea是理智,它不是.
PHP pg_escape_bytea似乎双重转义输出,因此它可以插入到字符串文字中.这非常难看,但似乎没有一个替代方法不会进行双重转义,所以你似乎无法在PHP中使用参数化语句来实现bytea.你还应该为其他一切做到这一点.
在这种情况下,只需addslashes从文件中删除读入数据的行就足够了.
显示pg_escape_bytea双逃逸的测试用例(并且总是使用旧的,低效的八进制转义):
<?php
# oh-the-horror.php
print pg_escape_bytea("Blah binary\x00\x01\x02\x03\x04 blah");
?>
Run Code Online (Sandbox Code Playgroud)
跑:
php oh-the-horror.php
Run Code Online (Sandbox Code Playgroud)
结果:
Blah binary\\000\\001\\002\\003\\004 blah
Run Code Online (Sandbox Code Playgroud)
看到加倍的反斜杠?那是因为它假设你要将它作为一个字符串插入到SQL中,这是一个非常低效,丑陋和非常糟糕的习惯.但是你似乎没有任何其他选择.
除此之外,这意味着:
pg_unescape_bytea(pg_escape_bytea("\x01\x02\x03"));
Run Code Online (Sandbox Code Playgroud)
...产生错误的结果,因为pg_unescape_bytea实际上并不相反pg_escape_bytea.这也使得它不可能的输出馈pg_escape_bytea入pg_query_params作为参数,你必须要插它.
如果你使用的是现代的PostgreSQL,它可能默认设置bytea_output为hex.这意味着如果我将数据写入bytea字段然后将其取回,它将看起来像这样:
craig=> CREATE TABLE byteademo(x bytea);
CREATE TABLE
craig=> INSERT INTO byteademo(x) VALUES ('Blah binary\\000\\001\\002\\003\\004 blah');
INSERT 0 1
craig=> SELECT * FROM byteademo ;
x
----------------------------------------------------------------------------
\x426c61682062696e6172795c3030305c3030315c3030325c3030335c30303420626c6168
(1 row)
Run Code Online (Sandbox Code Playgroud)
"嗯,什么",你可能会说?这很好,它只是PostgreSQL稍微更紧凑的十六进制表示bytea.pg_unescape_bytea将处理它很好并产生与输出相同的原始字节...如果你有一个现代的PHP和libpq.在老版本中,你会得到垃圾和需要设置bytea_output,以escape供pg_unescape_bytea处理它.
使用PDO.
它有理智(ish)的支持bytea.
$sth = $pdo->prepare('INSERT INTO mytable(somecol, byteacol) VALUES (:somecol, :byteacol)');
$sth->bindParam(':somecol', 'bork bork bork');
$sth->bindParam(':byteacol', $thebytes, PDO::PARAM_LOB);
$sth->execute();
Run Code Online (Sandbox Code Playgroud)
看到:
您可能还想查看PostgreSQL的lob(大对象)支持,它提供了一个仍然完全事务性的流式可搜索接口.
如果PHP在"字节字符串"和"文本字符串"类型之间有真正的区别,您甚至不需要pg_escape_bytea因为数据库驱动程序可以为您执行此操作.这些丑陋都不是必需的.不幸的是,PHP中没有单独的字符串和字节类型.
请尽可能使用PDO和参数化语句.
你不能,至少使用pg_query_params和参数化的语句.PHP addslashes不是替代品,它效率低,难看,并且不了解数据库特定的转义规则.bytea如果你因为icky历史原因没有使用PDO,你仍然需要手动转义,但其他一切都应该通过参数化语句.
有关指导pg_query_params:
pg_query_params| 归档时间: |
|
| 查看次数: |
16314 次 |
| 最近记录: |