By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,310 Members | 2,063 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,310 IT Pros & Developers. It's quick & easy.

First attempt at uploading image and storing to db

P: n/a
Hi,

I am trying to upload an image, create a new file based on that image
and then store the base64 encoded image data in a database.

I dont really know where my code is going wrong so I will just display
it below:

The following code contains the script to process the uploaded file,
the form to upload the file and then a few links to view the file from
a php script called simpleimageviewer.php:

<?php

//this file includes the function, 'dbconn()', that allows you to
//connect to the database
include('functions.php');

?>
<html>
<body>
<?php

//
if (isset($_GET['action'])) {
if (isset($_GET['action']) == "add") {
$tmpfilesize = $_FILES['imgfile']['size'];
$tmpfilename = $_FILES['imgfile']['tmp_name'];
$tmpfiletype = $_FILES['imgfile']['type'];
if ($tmpfilesize > 0) {
if (substr($tmpfiletype, 0, 6) == 'image/') {
//create image from uploaded image
switch ($tmpfiletype)
{
case "image/jpeg":
case "image/pjpeg":
$img = imagecreatefromjpeg($tmpfilename);
break;
case "image/gif":
$img = imagecreatefromgif($tmpfilename);
break;
case "image/png":
$img = imagecreatefrompng($tmpfilename);
break;
}
//create new file
$newfile = tempnam("/tmp", "img_");
//create jpeg and save as newfile
imagejpeg($img, $newfile, 80);
//open new file
$nf = fopen($newfile, "r");
//get contents of opened file and store in var
$filecontents = fread($nf, filesize($newfile));
//destroy file
fclose($nf);
unlink($newfile);

if ($filecontents) {
$insert = "INSERT INTO imglib (imgid, imgdata, imgtype) VALUES
(null, '" . base64_encode($filecontents) . "', '" . $imgtype . "')";
$result = mysql_query($insert, $db);
if ($result) {
echo "<p>Result!</p>";
}else{
echo "<p>No, no, no ... it didnt work</p>";
}
}
} else {
echo "<p>Please upload an image - wrong file type (" .
$tmpfiletype . ")</p>";
}
}else{
echo "<p>File not uploaded</p>";
}
}
}

?>
<form enctype="multipart/form-data" name="" method="post"
action="simple.php?action=add">
<input type="hidden" name="MAX_FILE_SIZE" value="5000000"><!-- approx.
5MB -->
<input name="imgfile" type="file"><br />
<input name="submit" type="submit" value="Submit">
</form>
<?php

$select = "SELECT * FROM imglib";
$result = mysql_query($select, $db);
if (mysql_num_rows($result) > 0) {
echo "<ul>\n";
while ($row = mysql_fetch_array($result)) {
$imgid = $row['imgid'];
echo " <li><a href=\"simpleimageviewer.php?imgid=" . $imgid .
"\">Image " . $imgid . "</a></li>\n";
}
echo "</ul>";
}

?></body>
</html>

Sorry about the mass of code but I thought I should just provide it
all. I also at some point need to resize the uploaded image so I seemed
the best idea to create a temporary file that I could play around with
before writing.

The problem is that when I go to view the image using the following
script (simpleimageviewer.php):
include('functions.php');

//IMAGE OUTPUT

$select = "SELECT imgdata, imgtype FROM imglib WHERE imgid = " .
$_GET['imgid'];
$result = mysql_query($select, $db);
while ($row = mysql_fetch_array($result)) {
$imgdata = $row['imgdata'];
$imgtype = $row['imgtype'];
}

//header
header("Content-type: " . $imagetype);
echo base64_decode($imgdata);
flush();
It doesnt display all the image. See
http://www.martynbissett.co.uk/test/...er.php?imgid=5 to
see what I mean. When I highlight the image it does show a lot of white
area that appears to have been a problem when creating the initial
image from the uploaded one.

Can anyone tell from my code what might be the problem, cheers

Burnsy

Aug 17 '05 #1
Share this Question
Share on Google+
11 Replies


P: n/a
Me again,

Think I know what the problem was. The image I was using was about
1200x1500px, when I resized the image (as I will do in my script
anyway) it should be ok.

Is there a maximum data size that datatype, 'text' can store in a
database or is there something else in the above script that is
limiting this? Cheers

Burnsy

Aug 17 '05 #2

P: n/a
On 16 Aug 2005 17:05:01 -0700, bi******@yahoo.co.uk wrote:
Think I know what the problem was. The image I was using was about
1200x1500px, when I resized the image (as I will do in my script
anyway) it should be ok.

Is there a maximum data size that datatype, 'text' can store in a
database or is there something else in the above script that is
limiting this? Cheers


Yes, 2^16 bytes = 64Kb, which won't get you very far for big images.
http://dev.mysql.com/doc/mysql/en/st...uirements.html

--
Andy Hassall / <an**@andyh.co.uk> / <http://www.andyh.co.uk>
<http://www.andyhsoftware.co.uk/space> Space: disk usage analysis tool
Aug 17 '05 #3

P: n/a
On 16 Aug 2005 16:56:33 -0700, bi******@yahoo.co.uk wrote:
I am trying to upload an image, create a new file based on that image
and then store the base64 encoded image data in a database.


A couple of suggestions for improvements:

MySQL can store binary data directly using the *BLOB types, which would avoid
the 33% size increase plus processing that you are incurring by base64 encoding
it.

You're writing the JPEG to a temporary file then reading back out again before
feeding into the database; another approach could be to use the output
buffering functions (ob_start() etc.) and then use imagejpeg without a filename
argument. You can then read the data out of the output buffer and into the
database without the intermediate temporary file.

--
Andy Hassall / <an**@andyh.co.uk> / <http://www.andyh.co.uk>
<http://www.andyhsoftware.co.uk/space> Space: disk usage analysis tool
Aug 17 '05 #4

P: n/a
> MySQL can store binary data directly using the *BLOB types, which would avoid
the 33% size increase plus processing that you are incurring by base64 encoding
it.


I was aware that my above method gave a 33% increase but I was just
wanting to accomplish uploading, storing and outputing at this stage.

Anyway, going on your advice above I have tried the following code when
the image is uploaded:

$tmpfiletype = $_FILES['imgfile']['type'];
switch ($tmpfiletype)
{
case "image/jpeg":
case "image/pjpeg":
$img = imagecreatefromjpeg($tmpfilename);
break;
case "image/gif":
$img = imagecreatefromgif($tmpfilename);
break;
case "image/png":
$img = imagecreatefrompng($tmpfilename);
break;
}

//write to db
$insert = "INSERT INTO imgblob (imgid, imgdata, imgtype) VALUES (null,
'" . $img . "', '" . $imgtype . "')";
$result = mysql_query($insert, $db);
if ($result) {
echo "<p>Result!</p>";
}else{
echo "<p>No, no, no ... it didnt work</p>";
}
Unfortetely, I am getting the 'No, no, no ... it didnt work' output
that indicates that it wasnt able to write the image to the database. I
am guessing that I need to do something with $img before I can use it
in the INSERT query. What do I need to do with $img to let me INSERT it
if this is the case?

Note: I have created a table called imgblob with a imgdata with type
'blob' instead of 'text' for use here

Cheers

Burnsy

Aug 17 '05 #5

P: n/a
On 17 Aug 2005 16:12:06 -0700, bi******@yahoo.co.uk wrote:
MySQL can store binary data directly using the *BLOB types, which would avoid
the 33% size increase plus processing that you are incurring by base64 encoding
it.
I was aware that my above method gave a 33% increase but I was just
wanting to accomplish uploading, storing and outputing at this stage.


OK, fair enough.
Anyway, going on your advice above I have tried the following code when
the image is uploaded:

$tmpfiletype = $_FILES['imgfile']['type'];
switch ($tmpfiletype)
{
case "image/jpeg":
case "image/pjpeg":
$img = imagecreatefromjpeg($tmpfilename);
break;
case "image/gif":
$img = imagecreatefromgif($tmpfilename);
break;
case "image/png":
$img = imagecreatefrompng($tmpfilename);
break;
}

So $img is a resource handle here.
//write to db
$insert = "INSERT INTO imgblob (imgid, imgdata, imgtype) VALUES (null,
'" . $img . "', '" . $imgtype . "')";
You don't want to write the string representation of a resource handle into
the database - it won't mean much. Also you want some escaping here - more so
since it'll be binary data now.
$result = mysql_query($insert, $db);
if ($result) {
echo "<p>Result!</p>";
}else{
echo "<p>No, no, no ... it didnt work</p>";
The dreaded "doesn't work" message :-( Make it more helpful with
mysql_error().
Unfortetely, I am getting the 'No, no, no ... it didnt work' output
that indicates that it wasnt able to write the image to the database. I
am guessing that I need to do something with $img before I can use it
in the INSERT query. What do I need to do with $img to let me INSERT it
if this is the case?

Note: I have created a table called imgblob with a imgdata with type
'blob' instead of 'text' for use here


Similar to the bit where you did imagejpeg to a temporary file, but instead
wrap it in buffering. This is just typed without testing:

ob_start();
imagejpeg($img, '', 80);
$imgdata = ob_get_contents();
ob_end_clean();

$insert = sprintf(
"INSERT INTO imgblob (imgid, imgdata, imgtype)
VALUES (null, '%s', '%s'),
mysql_real_escape_string($imgdata),
mysql_real_escape_string($imgtype),
);

Then go ahead and run the query.

You might also want a bigger datatype like MEDIUMBLOB or LONGBLOB.

--
Andy Hassall / <an**@andyh.co.uk> / <http://www.andyh.co.uk>
<http://www.andyhsoftware.co.uk/space> Space: disk usage analysis tool
Aug 17 '05 #6

P: n/a
I tried your line for INSERT but I think you may have left out a set of
quotes ("), and added an extra comma (,) so I tried the following:

$insert = sprintf(
"INSERT INTO imgblob (imgid, imgdata, imgtype)
VALUES (null, '%s', '%s')",
mysql_real_escape_string($imgdata),
mysql_real_escape_string($imgtype)
);

Unfortuntely that gave me the following error:

- Unknown column 'imgid' in 'field list'

Without really knowing too much about your code I cant really determine
what it is supposed to be doing here.

Anyway, I have went back to trying my old INSERT with the Output Buffer
code you provided but still didnt work:

//prepare image for database
ob_start();
imagejpeg($img, '', 80);
$imgdata = ob_get_contents();
ob_end_clean();

//write to db
$insert = "INSERT INTO imgblob (imgid, imgdata, imgtype) VALUES (null,
'" . $imgdata . "', '" . $imgtype . "')";
$result = mysql_query($insert, $db);
if ($result) {
echo "<p>Result!</p>";
}else{
echo "<p>No, no, no ... it didnt work</p>";
echo "<p>" . mysql_error() . "</p>";
}
Gave me the following error:

You have an error in your SQL syntax. Check the manual that corresponds
to your MySQL server version for the right syntax to use near
'*)-0-(0%()(' at line 1

Any ideas?

Burnsy

Aug 18 '05 #7

P: n/a
On 18 Aug 2005 02:49:21 -0700, bi******@yahoo.co.uk wrote:
I tried your line for INSERT but I think you may have left out a set of
quotes ("), and added an extra comma (,) so I tried the following:

$insert = sprintf(
"INSERT INTO imgblob (imgid, imgdata, imgtype)
VALUES (null, '%s', '%s')",
mysql_real_escape_string($imgdata),
mysql_real_escape_string($imgtype)
);
Ah, yes, I did warn you I hadn't tried it :-)
Unfortuntely that gave me the following error:

- Unknown column 'imgid' in 'field list'
Well, what's the definition of your table? I just copied your insert statement
and fixed it up to escape properly.

Looking back at your original post you have:

$select = "SELECT imgdata, imgtype FROM imglib WHERE imgid = ...

But then "imglib" changes to "imgblob" in the next post.
Without really knowing too much about your code I cant really determine
what it is supposed to be doing here.
It's putting the properly escaped values in the statement - and that's all.
Not doing much more than your previous insert statement, but yours won't work
as we can see in a moment...
Anyway, I have went back to trying my old INSERT with the Output Buffer
code you provided but still didnt work:

//write to db
$insert = "INSERT INTO imgblob (imgid, imgdata, imgtype) VALUES (null,
'" . $imgdata . "', '" . $imgtype . "')";
$result = mysql_query($insert, $db);
if ($result) {
echo "<p>Result!</p>";
}else{
echo "<p>No, no, no ... it didnt work</p>";
echo "<p>" . mysql_error() . "</p>";
}

Gave me the following error:

You have an error in your SQL syntax. Check the manual that corresponds
to your MySQL server version for the right syntax to use near
'*)-0-(0%()(' at line 1

Any ideas?
You MUST use mysql_escape_string or mysql_real_escape_string on the data
before you put it in the INSERT statement. Since it's binary data, odds are it
contains a quote or a NUL character, in which case it breaks out of the quotes
around it and produces syntax errors from the binary data that it's trying to
parse as SQL.
$insert = sprintf(
"INSERT INTO imgblob (imgid, imgdata, imgtype)
VALUES (null, '%s', '%s')",
mysql_real_escape_string($imgdata),
mysql_real_escape_string($imgtype)
);


This is what I was getting at with the modified $insert statement here. You
could just as well write it as:

$insert = "INSERT INTO imgblob (imgid, imgdata, imgtype) VALUES (null,'" .
mysql_escape_string($imgdata) . "', '" .
mysql_escape_string($imgtype) . "')";

At which point it'll probably start complaining about imgid again, since it
seems there's some issue with the table structure not matching what you've
posted?

--
Andy Hassall / <an**@andyh.co.uk> / <http://www.andyh.co.uk>
<http://www.andyhsoftware.co.uk/space> Space: disk usage analysis tool
Aug 18 '05 #8

P: n/a
My mistake, sorry. For some reason I had accidentally name the imgid
field on imgblob as imglib. All is well now.

Just one more question. The intended database where this concept will
work is PostgreSQL as this is what I work with when Im at work. At home
I practise on MySQL. I know the alternatives for stuff like mysql_query
and the connection stuff. What is the PG alternative to
mysql_real_escape_string()? Is it required? Can I simply use
mysql_real_escape_string() with PG?

Cheers

Burnsy

Aug 19 '05 #9

P: n/a
On 2005-08-19, bi******@yahoo.co.uk <bi******@yahoo.co.uk> wrote:
My mistake, sorry. For some reason I had accidentally name the imgid
field on imgblob as imglib. All is well now.

Just one more question. The intended database where this concept will
work is PostgreSQL as this is what I work with when Im at work. At home
I practise on MySQL. I know the alternatives for stuff like mysql_query
and the connection stuff. What is the PG alternative to
mysql_real_escape_string()? Is it required? Can I simply use
mysql_real_escape_string() with PG?


Have you even bothered to have a look at the manual?
http://www.php.net/pgsql (pgsql_escape_string)

Btw, why would you loose time with that if you can use prepared
statements/parameter binding?

--
Met vriendelijke groeten,
Tim Van Wassenhove <http://timvw.madoka.be>
Aug 19 '05 #10

P: n/a
> Have you even bothered to have a look at the manual?

Its a bit difficult when you dont know the command. How am I supposed
to check what pgsql_escape_string does when I dont even know that is
what I am looking for.

I did, however, check for pg_real_escape_string. Sometimes the PG
equivelant is easy to find (mysql_fetch_array -> pg_fetch_array and so
on)
Btw, why would you loose time with that if you can use prepared
statements/parameter binding?


Hmm, dont know that one. Explain please.

Aug 19 '05 #11

P: n/a
On 2005-08-19, bi******@yahoo.co.uk <bi******@yahoo.co.uk> wrote:
Have you even bothered to have a look at the manual?
Its a bit difficult when you dont know the command. How am I supposed
to check what pgsql_escape_string does when I dont even know that is
what I am looking for.


Well, it's pretty easy to type http://www.php.net/whatever_im_searching

In your case, i would probably type http://www.php.net/pgsql and look at
the available functions.
I did, however, check for pg_real_escape_string. Sometimes the PG
equivelant is easy to find (mysql_fetch_array -> pg_fetch_array and so
on)


I went to http://www.php.net/pgsql_real_escape_string and i saw that it
doesn't exist. But in the suggested list i see pg_escape_string.

Btw, why would you loose time with that if you can use prepared
statements/parameter binding?


Hmm, dont know that one. Explain please.


You can start reading at http://www.php.net/pg_query_params.
For more in depth info you might want to perform a websearch on
"prepared statements" / "parameter binding"

--
Met vriendelijke groeten,
Tim Van Wassenhove <http://timvw.madoka.be>
Aug 19 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.