Tuesday 23 April 2013

Handling Binary Data with PDO in PHP


We can handel binary data using PDO database access library in PHP 5 . In one project i am storing images in database as binary Data. PDO allows you to bind a file handle to a parameter in a prepared statement and when the statement is executed the contents of the file are slurped into the database. 
This works perfectly but the problem comes when getting the image out of the database again to display it. 
According to the PHP manual the following code should work:

$db = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2');
$stmt = $db->prepare("select contenttype, imagedata from images where id=?");
$stmt->execute(array($_GET['id']));
$stmt->bindColumn(1, $type, PDO::PARAM_STR, 256);
$stmt->bindColumn(2, $lob, PDO::PARAM_LOB);
$stmt->fetch(PDO::FETCH_BOUND);
header("Content-Type: $type");
fpassthru($lob);

Binding a column from a result set to a variable using PDO::PARAM_LOB is supposed to return a stream resource into the variable when PDO::fetch() is called. This stream can then be operated on using any PHP function that handles files. Unfortunately there’s a bug which means that instead of returning a stream into $lob PDO returns a string containing the binary data. When this is then passed to fpassthru() an error is triggered. Fortunately there’s a simple fix for displaying the image: replace the call to fpassthru() with echo or print. Since the browser is expecting an image after the call to header() writing the binary data. Using echo or print has the same effect as calling fpassthru(). In my code I’ve added the following just in case this bug is fixed in a future release:

if (is_string($lob))
      {
   echo $lob;
} else {
   fpassthru($lob);
}

//or we can use following code to convert string data into a stream first then continue accessing it as if it were a string.
if (is_string($lob)) {
// $lob is now a resource pointing to a stream composed of the data at hand
$lob = fopen('data://text/plain;base64,' . base64_encode($lob), 'r');

fpassthru($lob);

This neatly gets around the problem if you just want to send the binary data back to the browser to be displayed. Anything more requiring the use of any file functions or image editing functions would need quite a few contortions in the code. The information from the database would probably need to be written to a temporary file to allow it to be operated on.
This bug was first reported almost three years ago in PHP 5.2.6 and it’s still not fixed today in the most recent version, 5.3.1.

To encrypt data using mycrypt function


$key = 'mysalt password';

$string = 'string to be encrypted s%$%&*^$#@! <img src="hjdsfshjf/djfhskdhjf"> <a href="#">my link</a> my texy sample text sample text';

$encrypted = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string, MCRYPT_MODE_CBC, md5(md5($key))));

$decrypted = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($encrypted), MCRYPT_MODE_CBC, md5(md5($key))), "\0");


print_r($encrypted); //32
echo "<br>";
print_r($decrypted); //22

No comments:

Post a Comment