Outputing an Image from the database

They have: 38 posts

Joined: Jun 2008

Hi all,

I'm having some real trouble and I was wondering if anyone could help me.

I am creating a user systems where each user can have their own avatar, at the moment I am trying to figure out the best way to do this. I have been trying to upload their image to the database (which works great) and then output it on the page.

The problem I am having is that when I need to output the image I have to use the header(content-type: image/jpg);

I always get the cannot modify header error, because I have a header.php file that is included in every page that sets the title etc.

I am just really stuck on the best way to do this, what is the typical way that forums do it? I have been googling but nothing helpful has come up yet so I thought I would ask the experts.

Any help would be greatly appreciated!

Thanks All.

Relentless.

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

Yes, this is possible. Whenever you are generating an image with PHP, you need to do it in a separate PHP file. That is because images are treated as a separate HTTP request altogether.

Include their avatar just like a normal image:

<img src="/path/to/avatar/script.php" />

And then your avatar script will first set the JPEG header, then get the image data from the database, and then output only that image.

He has: 629 posts

Joined: May 2007

I am not clear on why you would store your images in a database? Conventionally storing them in their own folder has a number of advantages -- ability to prevent indexing and hot-linking among them. Most hosts are set up to deliver .gif .png and .jpg files with the correct MIME type, saving you the trouble.

I would have thought that storing just the URL to the image would serve your purpose(?).

Cordially, David
--
delete from internet where user_agent="MSIE" and version < 8;

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

I would have thought that storing just the URL to the image would serve your purpose(?).

Usually what I do is just give the avatar the filename of the unique ID in the database. So if somebody registers, and they get the id 120 in the DB, then their avatar will be /avatars/120.pg or something.

Storing it in the database eliminates the need to directly write to the filesystem which is a security risk in some hosting setups. It does have its drawbacks though. Fetching an image from a server takes next to no resources, but calling the PHP engine, connecting to the database, finding the record, and building the JPEG does take a bit of resources, and you will feel it with the site grows, especially if no caching is in place.

decibel.places's picture

He has: 1,494 posts

Joined: Jun 2008

FYI Drupal with the Avatar Selection module will handle this for you Smiling

I also take care of a non-Drupal site with user pics, which get processed to 4 different sizes and are stored in separate image directories, with filename stored in the database.

They have: 38 posts

Joined: Jun 2008

Thank you all so much for your help, I have managed to do it now!

Take a look Smiling

Again thank you Smiling

If you notice any bad points about the site please let me know, I could do with a few pointers, but most of it is not even uploaded yet so not much to evaluate.

Oh, and another thing, with having the images in the database, are there any extra security pre-cautions I should take?

Peace.
Relentless.

They have: 38 posts

Joined: Jun 2008

@decibel.places

Thanks for the post, but I am coding my own CMS to learn, plus I enjoy coding Smiling so using another CMS is not what I am looking for Smiling

Cheers though.

Relentless.

decibel.places's picture

He has: 1,494 posts

Joined: Jun 2008

IO.Relentless -

Yes, your site looked to me like a home-cooked job - and looks good! Smiling

I have grown weary of reinventing the wheel (unless it's a better wheel) so I like solutions that work out of the box (sure, I can't help tweaking them just a bit...)

With an enormous, active, and talented developer base, Drupal offers solutions to most tasks, letting me concentrate on the necessary custom programming!

One more thing - you may learn by examining the Drupal modules, even if you are not using the core...

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

Oh, and another thing, with having the images in the database, are there any extra security pre-cautions I should take?

As long as you are escaping that image_id variable, you should be good. Glad to see you got it working. Smiling

They have: 38 posts

Joined: Jun 2008

Thanks all again for your help! Laughing out loud you guys are a god sent Smiling

By escaping what do you mean exactly?

When I get input before I put it into a query I do mysql_real_escape_string() and if it is an int I always cast (INT)just to make sure. So I have done this with the other image properties, anything else need doing?

Thank you!
Relentless.

JeevesBond's picture

He has: 3,956 posts

Joined: Jun 2002

I believe you should also run images through mysql_real_escape_string(). I mean the image blob itself, otherwise you'll end up sucking as badly as ExpressionEngine. Smiling

Casting numeric input as (int) is, as you say, a good idea.

a Padded Cell our articles site!

decibel.places's picture

He has: 1,494 posts

Joined: Jun 2008

otherwise you'll end up sucking as badly as ExpressionEngine

I have had interest in EE but never a need/opportunity to try it.

Over the course of a few years, I have never seen a major security problem on live Drupal sites.

An old client showed me a site someone built in Joomla, with a nasty hack. I don't know if it was not installed properly, or perhaps the developer was disgruntled.

Anyway, JeevesBond is correct, be aware of security, particularly when users are uploading files or creating content.

They have: 38 posts

Joined: Jun 2008

Cool, thanks again! I will keep posting questions as I think of them if that is ok, it has been really helpful getting some professional responses and feedback.

Oh!, another one Smiling

I have a method of checking for online users but is there any articles/tutorials to methods that you would recommend I should implement?

Thanks and Peace.

Relentless.

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

I have a method of checking for online users but is there any articles/tutorials to methods that you would recommend I should implement?

The best way to check to see if they are online would be to log their last page view on their session. Then, determine if they are still online based on when they last viewed a page on your site.

JeevesBond's picture

He has: 3,956 posts

Joined: Jun 2002

Agreed with pr0gr4mm3r here, most 'online' indicators just show whether the user has viewed a page within the last 15 minutes.

They have: 38 posts

Joined: Jun 2008

Great, thank you for the tip Smiling

At the moment I am looking at recoding the whole site! because I have been looking at OO PHP. What are your views on this? I have done OOP in C# so have most of the methodology down. Just need to time to learn the implementation.

Cheers,
Relentless.

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

OO programming in my opinion is way better and much more organized. You may also want to look into the MVC approach. I always follow both of these techniques for my PHP applications, and it makes them much more manageable.

They have: 38 posts

Joined: Jun 2008

Thanks, I have heard of the model view controller approach before. unfortunately, I don't have that much spare time on my hands at the moment, so diving head first into OO PHP is not my best option, I will continue building my site old school for now while learning about OO PHP, and we will see that happens Smiling

I am having some problems with this bit of code!

if($_SESSION['username'] != $v_author) {
$update_reads = $v_reads + 1;
$rq = "UPDATE articles SET reads='$update_reads' WHERE id='$v_id'";
$rr = mysql_query($rq, $conn) or die("Could not update reads, Error: " . mysql_error());
}

I get the following error:

Could not update reads, 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 'reads='46' WHERE id='3'' at line 1

The values are correct, it just seems that mysql_query() does not like something xD any ideas?

Thank you all again,
Relentless.

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

Looks like your problem is that you are using a reserved word in your query as a column name, in this case "reads". You can do that, but you need to use the backquotes (`) around that column name, so your query would look like this:

UPDATE articles SET `reads` = '46' WHERE id = '3'

They have: 38 posts

Joined: Jun 2008

Sorted thank you! Laughing out loud

The only problem now is, every time the page refresh it classes it as a new read :S

Any thoughts on a way to implement a better system?

Thank you all sooooooooooo much! Smiling Laughing out loud

Relentless.

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

Glad to help Smiling.

Well...you are going have to store more information about the page view if you are going to tell the difference between a unique hit and a repeat hit.

One option is to map their IP addresses. This is the easiest method to implement, but it has faults. If a page gets attention on a large campus or company network, your statistics won't show it because it all comes from the same IP.

The other option is to set a cookie on the user's computer. This takes a bit more code, and it won't work if the visitor doesn't accept cookies, but most do these days, and I think that would be the better option. All you would have to do is store a value in a cookie that you would check for to determine if it's a repeat visit or not.

They have: 38 posts

Joined: Jun 2008

Excellent, thanks again Smiling

I will have a look at a way to implement this, need to do some googeling Smiling

Just finished the Article comment system Smiling

Relentless.

pr0gr4mm3r's picture

He has: 1,502 posts

Joined: Sep 2006

Not a problem. Good luck with your web application. I find coding PHP sites from scratch quite enjoyable as well as a valuable learning experience.

They have: 38 posts

Joined: Jun 2008

Amen to that.

Even though I may not be coding with the latests technology or OO PHP I am still enjoying the learning experience. I am trying to concentrate on security, I am attempting to incorporate login attempt logs so each user can see if anyone has been trying to login with their account, which I believe will not only benefit the users but me the administrator as well. I am looking for the best way to change passwords and such too, maybe the password should just be sent to the registered e-mail in plain text, or should it be re-set? And if the re-set option is chosen then maybe it should only be allowed within a time limit and on the same IP address. For example a user clicks "Reset Pass" a reset email is then sent to the registered email address saying you have 1 hour to click this link, using this IP address. But I believe this could cause many problems. What do you all think? Know of any interesting articles related to this?

Thanks all again,
Relentless.

Want to join the discussion? Create an account or log in if you already have one. Joining is fast, free and painless! We’ll even whisk you back here when you’ve finished.