3 replies [Last post]
Happs
Happs's picture
Offline
Enthusiast
Manchester, UK
Last seen: 11 years 7 weeks ago
Manchester, UK
Joined: 2005-10-30
Posts: 54
Points: 7

Hey People.

OK .. DAYS literally DAYS worth of trying has lead me to ask you guys.
I am trying to make a script that a) uploads a jpeg to a mySQL database (blob) and then b) retrieve AND display it.

I have literally TRIED EVERY SCRIPT ONLINE! I've checked my php settings and they're all correct so why oh why does it just return a load of garbage ??

The image is successfully on the database, and the browser does get the blob data, but just doesn't display it as an image.

Here's the PHP:

<?php
global $blobId;
$blobId = "1"; //set the blobId for debugging purposes
if(!is_numeric($blobId))
die("Invalid blobId specified");
require_once ('connecttodatabase.php'); //connects to the database
$dbQuery = "SELECT blobType, blobData ";
$dbQuery .= "FROM myBlobs ";
$dbQuery .= "WHERE blobId = $blobId";
$result = mysql_query($dbQuery) or die("Couldn't get file list");
if(mysql_num_rows($result) == 1)
{
$fileType = @mysql_result($result, 0, "blobType");
$fileContent = @mysql_result($result, 0, "blobData");
header("Content-type: $fileType"); //type is correct as image/jpeg
echo $fileContent; // displays garbage instead of image
}
else
{
echo "Record doesn't exist.";
}

?>

Please if anyone can help!!!! I'm going mental! lol

- Alex

Tags:
ro88o
ro88o's picture
Offline
Enthusiast
Manchester, UK
Last seen: 14 years 38 weeks ago
Manchester, UK
Joined: 2005-06-29
Posts: 202
Points: 0

Arrgh!! PHP &amp; MySQL file handling. *RESOLVED*

This is how I display images on my site. 'image_name' will be a name of a file e.g. pic.gif, in the images folder and is retrieved from the database.
<img src="images/<?php echo urlencode($image_name); ?>">
The important part being the urlencode to stop it displaying garbage.

www.nubornis.com
Web Development and E-commerce Solutions.

Chris..S
Chris..S's picture
Offline
Moderator
Last seen: 10 years 20 weeks ago
Timezone: GMT+1
Joined: 2005-02-22
Posts: 6078
Points: 173

Arrgh!! PHP &amp; MySQL file handling. *RESOLVED*

Have you checked the headers your browser is receiving?

Isolate the problem into different parts and check each bit in isolation from the rest.

(1) Forget the db. Place a known good jpg on your server. See if you can send it to your browser. Comment out your db retrieval code and replace it with "readfile(/path/to/good.jpg);" (this is where functionalisation in your script would come in handy).

(2) If that doesn't work, check the response headers the browser is receiving. Fix those.

(3) Manually load the good jpg into your db. Manually retrieve it, do a binary file comparison on the two to make sure they are identical.

(4) Put back your database retrieval code, retrieve the image and send it to the browser.

(5) If things still don't work, change your retrieval code to save a copy of the image on the server. Do a file comparison with the original.

I'd reckon if you complete all the above its very unlikely you'll still have a problem. If you do, at least you'll know what part is causing the problem and you'll know where to look to fix it.

I have to ask though. Why are you storing images in a database? Why not store them on disk and save the name in the db?

If security is an issue, place the image in an unreachable part of the website and use a php handler to ensure the requests are legitimate and allow the php handler to send the image.

Letting a webserver send a file straight to the user is very quick. If you are going to put a php script in the way, you will want to set headers that allow the image to be cached by the browser.

Happs
Happs's picture
Offline
Enthusiast
Manchester, UK
Last seen: 11 years 7 weeks ago
Manchester, UK
Joined: 2005-10-30
Posts: 54
Points: 7

Done it :)

Deary deary deary ME! Finally! ...

Thankyou Chris & ro88o. This is how I resolved it ...

I made a new document called view_image.php and hardcoded both the image ID and the Header Type ...

<?php
require_once ('connecttothedatabase.php'); //connect to database
$sql    = "SELECT * FROM image WHERE image_id=1"; //select one ID from the database
$result = mysql_query ($sql);
if (mysql_num_rows ($result)>0) {
  $row = @mysql_fetch_array ($result);
  $image = $row["image"];
  header ("Content-type: image/gif"); // hard-coded content-type
  echo $image;
}
?>


This, however didn't work, but it did allow me to check that the code was retrieving the binary data correctly and therefore displayed a bunch of garbage.

Then I checked the response Headers (thanks Chris) and it wasn't just a header; it was the database password and connection information too!

So I took out the

require_once ('connecttothedatabase.php'); //connect to database

And replaced it with
<?php
define ('DB_USER', 'username');
define ('DB_PASSWORD', 'password');
define ('DB_HOST', 'localhost');
define ('DB_NAME', 'db_name');
$database = @mysql_connect (DB_HOST, DB_USER, DB_PASSWORD) or die ('<b>Sorry, this page is temporarily unavailable. We are working hard to rectify the problem.<br /> <font color="#ff0000">COULD NOT CONNECT TO DATABASE:</font></b><br /> ' . mysql_error() );
mysql_select_db (DB_NAME) or die ('<b>Sorry, this page is temporarily unavailable. We are working hard to rectify the problem.<br /> <font color="#ff0000">UNABLE TO SELECT REQUIRED DATABASE:</font></b><br /> ' . mysql_error() );

$sql    = "SELECT * FROM image WHERE image_id=1";
$result = mysql_query ($sql);
if (mysql_num_rows ($result)>0) {
  $row = @mysql_fetch_array ($result);
  $image = $row["image"];
  header ("Content-type: image/gif");
  echo $image;
}

So, it was the require_once section that was causing incorrect header type.

WORD! Now I can get on with the website!

- Alex "Very HAPPY!" Happs

P.S. Oh and as for storing image information within the database ... it will contain a maximum of ten 90x90 jpegs so I'm not too fussed atm about it. But thanks for the pointers Laughing out loud

Oh and !EDIT!> hehe ..

I found out the reason why the require_once part was messing it up was because of whitespace within the database connect script, so I've gotted rid of all that DEFINE area now and reverted BACK to the require_once idea.

LOL.. someone turn off VERBOSE mode! heheh

- Alex