0

I've been storing the contents of zip files in a LONGBLOB in a MySQL database, but I'm moving to Postgres. From what I've read, the equivalent to LONGBLOB in Postgres is bytea. Unfortunately, I can't get the zip contents to write to the database. First, I got this error:

Warning: pg_query(): Query failed: ERROR:  invalid byte sequence for encoding "UTF8"
 0x5c

Then I created a new database with SQL_ASCII encoding (the previous had UTF8), and got this error:

PHP Warning:  pg_query(): Query failed: ERROR:  syntax error at or near "v╘▓ú5"
LINE 2: ...√╢V[úB√▬┌»å⌐²└ù╙±b±≡ß▼┐π}°ï»┌G╜₧╧εo»~°0o╞W/_╝ƒL¢\'v╘▓ú5;Ω░#╩...

Is there any way to create a database/table/column in Postgres without encoding? If not, how should I store this information? I tried using pg_escape_bytea but that produces errors when I try to unzip the contents. Not sure that this really matters, but here's the PHP I'm using to write to the database:

$content = file_get_contents($zipLocation);
$content = addslashes($content);

$sql="INSERT INTO ZIP_TBL ( BUILD, CONTENT)
    VALUES ('$build', '$content')";

if (!pg_query($con,$sql)) {
    die('Error: ' . pg_last_error($con));
}
2
  • Can't you use a bound parameter and let the PostgreSQL driver deal with properly encoding the binary data? Commented Aug 4, 2014 at 20:59
  • Never, ever, ever use addslashes. If you're using it, that's a giant flashing warning saying "probable security bug here". In this case you should clearly be using a parameterzed query. Commented Aug 5, 2014 at 1:09

3 Answers 3

3

One of the bytea input formats is hexadecimal. So use bin2hex

$content = file_get_contents($zipLocation);
$content = '\\x' . bin2hex($content);

$sql="
    insert into zip_tbl ( build, content)
    values ('$build', E'$content')
";

http://www.postgresql.org/docs/current/static/datatype-binary.html#AEN5318

http://php.net/manual/en/function.bin2hex.php

BTW, if you are not aware, you are susceptible to SQL injection.

Sign up to request clarification or add additional context in comments.

1 Comment

This worked for me, I just had to use $content = substr($content, 2); and $content = hex2bin($content); when reading it from the database
2

Now is a good opportunity to switch to PDO, which does this sort of thing cleanly and sanely.

Here's an earlier answer I wrote on this topic, which discusses the numerous ways in which the old-style PostgreSQL driver is truly awful for binary data.

The short version is that your code should be more like:

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

1 Comment

Thanks for the answer! Definitely helpful, although I ended up using Clodoaldo's method.
0

Try to use base64encode() function:

$content = file_get_contents($zipLocation);
$content = base64encode($content);

$sql="INSERT INTO ZIP_TBL ( BUILD, CONTENT)
    VALUES ('$build', '$content')";

if (!pg_query($con,$sql)) {
    die('Error: ' . pg_last_error($con));
}

And when you will need this data back, use base64decode() function. Also, type of your column needs to be text to store this data.

string base64_encode ( string $data )

string base64_decode ( string $data [, bool $strict = false ] )

http://php.net//manual/en/function.base64-decode.php

http://php.net//manual/en/function.base64-encode.php

3 Comments

Using this method I don't see any errors writing to the database, but when I try to read from the database the zip file is still corrupted ( I didn't forget to use base64_decode). I could post the php code I'm using to read from the database if that would help.
i wrote simple script to test it at my local machine and it's all right. Paste your code, will check it
You might need to change database collation

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.