tags:

views:

264

answers:

2

i know some of you are going to say that this isnt the correct way but im on a tight deadline to finish an application and as of now i cant go back and modify the code to store the images in a directory.

now that thats cleared

the question i had is i inserted an image into the database by typing this.

(dont mind the class security call, all that is doing is a few checks if the data is valid)

$filename = $security->secure($_FILES['imgschool']['name']);
$tmpname = $security->secure($_FILES['imgschool']['tmp_name']);
$imgsize = $security->secure($_FILES['imgschool']['size']);
$imgtype = $security->secure($_FILES['imgschool']['type']);
$school = $security->secure($_POST['school']);


//begin upload
if($imgsize > 0) {
$handle = fopen($tmpname, "r");
$content = fread($handle, filesize($tmpname));
$content = addslashes($content);

//code to add all this to database
}

the variable $content is the image and all its getting is the addslashes. i remember someone once mentioning to do it with something called base64 but i can barely recall how it was written.

this is how i am calling the image from the database

aside from all the queries and whatnot this is the main part that is calling the image

header("Content-length: ".$imgsize);
header("Content-type: ".$imgtype);
header("Content-Disposition: attachment; filename=".$imgname);
print $row['img'];

the problem i am having is that instead of the image showing. the url is only showing, so in this case i only see this

http://localhost/admin/school-catalog.php?page=gallery&id=4

when opening the page to view the image with the correct params set in the url.


for those that wanted to see the query that is being done to save the image and so forth i copied the whole section

//save image to db
if(isset($_POST['btnupload'])) {

$filename = $security->secure($_FILES['imgschool']['name']);
$tmpname = $security->secure($_FILES['imgschool']['tmp_name']);
$imgsize = $security->secure($_FILES['imgschool']['size']);
$imgtype = $security->secure($_FILES['imgschool']['type']);
$school = $security->secure($_POST['school']);


//begin upload
if($imgsize > 0) {
$handle = fopen($tmpname, "r");
$content = fread($handle, filesize($tmpname));
$content = base64_encode($content);
}

$save = mysql_query("insert into tbl_schoolgallery(id,hash,img,imgtype,imgsize) values(null,'$school','$content','$imgtype','$imgsize')") or die(mysql_error());
header("Location: school-catalog.php?page=school_gallery");

}


//call image from db
$query = mysql_query("select * from $tbl where id = '$id'") or die(mysql_error());
while($row = mysql_fetch_assoc($query)) {

$imgtypeget = explode("/", $row['imgtype']);

$imgname = "img.".$imgtypeget[1];
$imgtype = $row['imgtype'];
$imgsize = $row['imgsize'];

header("Content-length: ".$imgsize);
header("Content-type: ".$imgtype);
print base64_decode($row['img']);

print $row['img'];
}
A: 

http://www.phpro.org/tutorials/Storing-Images-in-MySQL-with-PHP.html gives a nice overview, including the use of a database abstraction library, which will make it so you don't have to use addslashes() on a binary value...

Thomas G. Mayfield
Your link is suggesting:$imgData =addslashes (file_get_contents($_FILES['userfile']['tmp_name']));So it still *does* make you use addslashes on a binary value. You should really just use mysql_real_escape_string.
Zarel
Further investigation on my link did in fact give bad advice. Isn't the Internet full of it? :) I'd read a copy/paste of that same article that used PDO but was formatted poorly, and stupidly assumed it was a direct copy of the original article. Updated to the tutorial that I actually vetted.
Thomas G. Mayfield
+5  A: 

Using addslashes is extremely incorrect. Depending on whether your column is a TEXT field or a BLOB field, you should use Base64 or mysql_real_escape_string.

Using Base64 isn't that hard; you may as well use that way. Just replace addslashes with base64_encode and echo the image with base64_decode.

There's a bit easier way to write the whole thing, for that matter:

// begin upload
if ($imgsize > 0)
{
  $content = file_get_content($tmpname);
  $content = base64_encode($content);
}

And then to output you really only need to do

header("Content-type: ".$imgtype);
echo base64_decode($img);

If the column is a BLOB, however, you can directly use mysql_real_escape_string:

// begin upload
if ($imgsize > 0)
{
  $content = file_get_content($tmpname);
  $content = mysql_real_escape_string($content);
}

And then:

header("Content-type: ".$imgtype);
echo $img;

Although judging from your current symptoms, I'm guessing you also have a bug relating to how your image is being stored and recalled from the database, and I'd need to see that part of the code where you make the queries to insert and read from the database before I could help you fix that part.


Your current code seems mostly fine. A few issues:

print base64_decode($row['img']);

print $row['img'];

You probably meant to get rid of the second row. Also, you should use echo instead of print; everyone uses it, it can be slighty faster sometimes, and print doesn't really have any benefit other than returning a value:

echo base64_decode($row['img']);

$security->secure() appears to be some sort of sanitization function. Just use mysql_real_escape_string() - that's the one you're supposed to use. Except $imgsize; you might want to use intval() on that one since you know it's supposed to be an integer.

Also here:

$query = mysql_query("select * from $tbl where id = '$id'") or die(mysql_error());

You name the table tbl_schoolgallery a few rows above that. I assume $tbl == 'tbl_schoolgallery', but for consistency, you should either use $tbl in both places or tbl_schoolgallery in both places.

Also, replace that while with an if - your code would cause trouble if it ever loops more than once, anyway.

Zarel
i added the blob of code :p can you review it. thank you for your time.
SarmenHB
I reviewed it. You're welcome. :)
Zarel
i have a feeling this is where the error is at: $tmpname = $security->secure($_FILES['imgschool']['tmp_name']);what the class is doing is its trowing a value trough mysql_real_escape_string and htmlencode. so the temporary image file is going through that which destroys it lol. funny thing is im using a 3rd party database viewer and im able to see the image clearly inside the databse.
SarmenHB
Yeah, you don't need to secure $tmpname.
Zarel