Uploading a Graphic to Database

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

I just noticed the line

Code: Select all

// move_uploaded_file($_FILESї'userfile']ї'tmp_name'], "../../images/Contests/");
in your script. If you have decided not to store the binary data in the database stop reading and say so ;)

-----

I don't know your table structure or how a record set is initially created in your system. So the only thing I can do is to give you an example.
Let's assume a (simple) table 'contests' having

Code: Select all

`id` tinyint(3) unsigned NOT NULL auto_increment,
`startdate` date default NULL,
<-- much more plain data here -->
`graphics` blob,
UNIQUE KEY `id` (`id`),
KEY `id_2` (`id`)
You probably have a script where you output the list of contests. Something like

Code: Select all

$query = 'SELECT id,startdate,... from contests';
$result = mysql_query($query, $conection) or die(mysql_error());
while ($row = mysql_fetch_array($result))
	prettyOutputRow($row);
to add the picture to this output you have to add an <img>-element to the document. Unfortunately you cannot add the image data directly to the same page (there is a way to add base64-encoded image data inline, but afaik it's netscape-only).
The common way is to add a src-attribute containing the source-url for the image data (<img src="image1.png"/>). So you will add a url pointing to a php-script that will pull the appropriate image-data from the db when requested. Appropriate means the image related to a certain 'contests'-entry identified by its unique identifier (in this example the field 'id').
In prettyOutputRow($row) you have to add something like

Code: Select all

echo '&lt;img src="contestImg.php?contestid=', $row&#1111;'id'], '" /&gt;'
so the client browser will 'see' something like

Code: Select all

...contest starts at 2002/09/30&lt;br/&gt;
&lt;img src="contestImg.php?imgid=2"/&gt;...
it will then request the image data for the <img>-element. whatever data is returned 'from' this url (contestImg.php) should be only the imagedata preceded by a "content-type- (and optionally but good behaviour a"content-length"-) header.
All you have to do in this script is to fetch the argument ($_GET['contestid']) and query the related image data

Code: Select all

&lt;?php
if ($_GET&#1111;'contest'])
{ 
/* &lt;-- data base connection code here --&gt; */
	// as mentioned the image-type-handling I leave up to you
	// assuming png for now
	header('Content-type: image/png');  

	// only querying the field &lt;graphics&gt;, nothing else needed
	// and only the record of the requested contest
	$query ='SELECT graphics from contests WHERE id='.(int)$_GET&#1111;'contest']; 

	// any error logging to the log-file, since Content-type: image/png already set
	$result = mysql_query($query, $conn) or die(error_log('imgData query failed')); 

	if ( ($row = mysql_fetch_row($result)) !== FALSE)
	{ // if a feasable record-set was found, return the graphics-data (if there's any)
		if (!is_null($row&#1111;0]))
			echo $row&#1111;0]; 
		else
			defaultNoPicture(); // no picture provided (yet)
	}
	else
		// if no such record was found (malformed request?) display an error-image (optional)
		echoErrorImage(); 
}
else
	echoErrorImage();
?&gt;
now back to the INSERT-problem. My code-snippet is not useful for this context. You may have already changed it to your needs and included it to the query that creates the 'contests'-entry, maybe you want the system to allow a change of the image data by authorized users.
to do this you have to provide not only the image-data but also the contest-id (somewhere the data has to be replaced and the script has to know)
(contestimgupload.php):

Code: Select all

if (isset($_POST&#1111;'contestid']))
{
/* &lt;-- data base connection code here --&gt; */
/* &lt;-- ingenious code to determine wether the user is allowed to change this data or not --&gt; */
	if (isset($_FILES&#1111;'graphic']) &amp;&amp;  is_uploaded_file ($_FILES&#1111;'graphic']&#1111;'tmp_name'])) 
	{ 
		$data = ''; 
		/* reading the (binary) uploaded data */ 
		$fd = fopen($_FILES&#1111;'graphic']&#1111;'tmp_name'], 'rb'); 
		while($nextpart = fread($fd, 4096)) // or some other 
			$data .= $nextpart;    // tricky read-method  
		fclose($fd); 
		unlink($_FILES&#1111;'graphic']&#1111;'tmp_name']); 
		/* request replacement of blob data  */ 
		$queryG = "UPDATE contests set graphics='". mysql_escape_string($data) ."' WHERE id=".$_POST&#1111;'contestid']; 
		mysql_query($queryG, $connection) or die('volka is dumb! '.mysql_error()); 
		/* if ( mysql_affected_rows($connection) == 0)
				&lt; the code at the top of the page wasn't that ingenious  &gt;
		*/
		echo 'image data for contest #',$_POST&#1111;'contestid'],' has been updated';
	}
	else
		print ("no image data provided."); 
}
add a hidden field to your form that will transport the contestid from the script that creates the form to the upload-script.
The script to create the form is very similar to the 'overview'-script. Maybe a little more complex select-statement to show only contest-records the user is allowed to change (nevertheless you have to check this in the script that performs the upload).
in the function prettyOutputRow you now will print something like

Code: Select all

&lt;?php ...
function prettyOutputRow($row) {
echo '&lt;fieldset&gt;&lt;legend&gt;contest #', $row&#1111;0],'&lt;/legend&gt;'; // id was the first field selected
...
?&gt;
	&lt;form enctype="multipart/form-data" method="post" action="contestimgupload.php"&gt;
		&lt;input type="hidden" name="contestid" value="&lt;?php echo $row&#1111;0]; ?&gt;"/&gt; &lt;br/&gt;
		&lt;input type="file" name="graphic" /&gt; &lt;br/&gt;
		&lt;input type="submit" /&gt;
	&lt;/form&gt;
	...
&lt;/fieldset&gt;&lt;?php
}
(all scripts untested)
some parts are still open (i.e. deleting the image data) but I already have to explain to somebody why I'm still sitting at my PC (sunday, 8am) ;)
User avatar
Zoram
Forum Contributor
Posts: 166
Joined: Sun Aug 18, 2002 3:28 pm
Location: Utah
Contact:

Post by Zoram »

I am feeling extremely dumb, I still can't seem to make any sense of this. Assuming that i already have the data saved in the database. How about a page that just displays the img. (say the only on the page is the <img src="contestImg.php?id=2"> how would i write the contestImg.php to get the data (a jpeg) from the server and display it?

Sorry for being so dense but for this 18 year old it's not making total sense... :oops:
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

the script next to All you have to do in this script is to fetch the argument ($_GET['contestid']) and query the related image data is meant to do this.

Since this is the second time a thread with this topic and my participation grew this large, it's likely that it is at least one of the following
  • complicated
  • done wrong/too intricate by me
To keep the images as files on your server and to only store the file's name in the db is a bit simpler and is prefered by many people.
I think it depends on the amount of data stored and the complexity of the surrounding framework. For low data amounts I prefer to store the binary data in the database, because I don't have to care for data-integrity. recordset gone, image data gone.
User avatar
Zoram
Forum Contributor
Posts: 166
Joined: Sun Aug 18, 2002 3:28 pm
Location: Utah
Contact:

Post by Zoram »

Alright, i've tried to simplify it a little and so far this is what;s happening:

I've got it to upload the graphic to the server and when i just echo it ou comes :

Code: Select all

....ׇ+îÒà›wêjÖQJÙ^Piµ·Wòî¤ÍÎ*í¹ äØÛ µm&#123;+C+¢„ÞÖumYRt*ìÉýzìžõãÞ¼jö?©~‹Ý&#125;“Õ“U“U“U“Õ“Ö”~îÒÝz=û&amp;«'¤
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

I think it doesn't make sense to continue in the forum. It's only getting worse.
My icq-number is: 151017995
Nenad
Forum Newbie
Posts: 1
Joined: Mon Sep 30, 2002 3:53 am
Location: MN

Post by Nenad »

I didn't read all replies, but did you try to store information about image location in the DB and upload image in some directory on server via GET method.

Than you make the query and show image like <img src=$url_of_the_image>.

It's very simple solution.
User avatar
Zoram
Forum Contributor
Posts: 166
Joined: Sun Aug 18, 2002 3:28 pm
Location: Utah
Contact:

Post by Zoram »

No i didn't really think about that, is it easier to do that then to upload it the DB?
User avatar
gijs
Forum Commoner
Posts: 53
Joined: Wed Aug 28, 2002 4:05 am
Location: Belgium

Check it out

Post by gijs »

Hi Zoram,

Check out this article I found on "Uploading Binary files to mySQL"
http://www.php4.com/forums/viewtopic.php?t=6
and read the rest of the posts concerning this article as well.

I'm a complete newby as well, but I adapted It and got it up and running in less then 20 minutes.

It's a veeeeery small forum, so won't get lost :wink:

Oh yeah, transmit my regards to b0nfire (the admin). He's cool 8)

HIH,

Gijs
Post Reply