The proper way to "echo" and image?

How can I:

<?php
echo file_get_contents('calendar.gif');
?>

I guess my problem is probably needed to put headers, any help?
LVL 5
mnb93Asked:
Who is Participating?
 
Richard QuadlingSenior Software DeveloperCommented:
No matter what mechanism you use to get the bytes of the image to the client, you will ALWAYS need to supply the appropriate headers. This is essential.

The reason for fpassthru is local memory usage.

The appropriate headers will still need to be sent.

Maybe something like this ...

<?php
// /home/www/site/private is OUTSIDE of the webroot, which means users MUST use this program to access the images.
define ('IMAGE_LOCATION', '/home/www/site/private/images/');

// Has an file been asked for, does it exist, is it a picture and can we open it.
// You may want to use some sort of indexing mechanism rather than the real image name.
if (
      isset($_GET['imagename']) && 
      file_exists(IMAGE_LOCATION . $_GET['imagename']) && 
      (False !== ($am_image_data = @getimagesize(IMAGE_LOCATION . $_GET['imagename']))) &&
      (False !== ($fp_image = @fopen(IMAGE_LOCATION . $_GET['imagename'], 'rb')))
      )
      {
      // Send the appropriate mime header.
      header('Content-type: ' . $am_image_data['mime']);
      header('Content-length: ' . filesize(IMAGE_LOCATION . $_GET['imagename']);

      // Stream the image.
      fpassthru($fp_image);

      // Always exit.
      exit;
      }
else
      {
      // You may want to supply an image which contains the words "Image not found.".
      }
?>
0
 
TomeeboyCommented:
Little bit confused why you would want to use file_get_contents for this.. any particular reason?

I think you would normally just do this:

echo "<img src='calendar.gif'>";
0
 
mnb93Author Commented:
Yes but lets say that I want to open an image and then "echo" it.
I know how to include it in (x)html however this is different.
0
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

 
TomeeboyCommented:
file_get_contents will create a string of the binary contents of your image, which means echoing it will just spew out a bunch of binary code.  If you insist on using that method, you could create a PHP file that would output the image with the correct header:

header('Content-type: image/gif');
echo file_get_contents('calendar.gif');

Then call that file from an image tag src:

echo "<img src='getimage.php'>";

Or add support for multiple images and send the ID of the image in the query string (ex: getimage.php?id=1)

Something like that..
0
 
Richard QuadlingSenior Software DeveloperCommented:
You are probably better off using fpassthru();


From the PHP Manual ...

<?php

// open the file in a binary mode
$name = './img/ok.png';
$fp = fopen($name, 'rb');

// send the right headers
header("Content-Type: image/png");
header("Content-Length: " . filesize($name));

// dump the picture and stop the script
fpassthru($fp);
exit;

?>


Rather than file_get_contents(). Mainly due to a waste of memory. If the image is a nice 118,000 pixel square of Orion, this COULD be a 24MG image (yep! I have one!).

Now with file_get_contents(), you are going to be actually loading that into the servers memory.

fpassthru() simply pushes the bytes to the browser.

A lot cleaner.
0
 
Richard QuadlingSenior Software DeveloperCommented:
If the image has been created using the image functions, then you can use ...

From the PHP Manual ...

<?php
if (function_exists("imagegif")) {
    header("Content-type: image/gif");
    imagegif($im);
} elseif (function_exists("imagejpeg")) {
    header("Content-type: image/jpeg");
    imagejpeg($im, "", 0.5);
} elseif (function_exists("imagepng")) {
    header("Content-type: image/png");
    imagepng($im);
} elseif (function_exists("imagewbmp")) {
    header("Content-type: image/vnd.wap.wbmp");
    imagewbmp($im);
} else {
    die("No image support in this PHP server");
}
?>

where in the above code, $im is the image resource created using the image functions.
0
 
alain34Commented:
may be a good idea is to use a class supporting already the 'echo' of an image and that also we provide you with additional transformation functionality.
2 for the price of 1.
Have a look at http://phpthumb.sourceforge.net/
0
 
mnb93Author Commented:
@You are probably better off using fpassthru();

Perfect except for one thing, I need the most optermised(fastest) way to add the mime type. (I am guessing that you would need to stuff round with the filename.
Because I know that I will be using PNG JP[E]G GIF.
0
 
Richard QuadlingSenior Software DeveloperCommented:
The above code is not ultra secure. Personally I would add session control to only allow known users to access the images.

Say the above code is called getimage.php. You wouldn't want a script kiddie to come along with a little program guessing all the image names!

By using sessions, you first make sure you know who the user asking for the images is.

0
 
mnb93Author Commented:
Why is that code not secure? (Or are you only saying that because there is not authentication?
0
 
Richard QuadlingSenior Software DeveloperCommented:
Yes.

I could simply attempt to access ANY image by ...

http://www.site.com/getimage.php?imagename=guess1.jpg
http://www.site.com/getimage.php?imagename=guess2.jpg
http://www.site.com/getimage.php?imagename=guess3.jpg
http://www.site.com/getimage.php?imagename=guess4.jpg
http://www.site.com/getimage.php?imagename=guess5.jpg
http://www.site.com/getimage.php?imagename=guess6.jpg
http://www.site.com/getimage.php?imagename=guess7.jpg
http://www.site.com/getimage.php?imagename=guess8.jpg

If I come across the site which uses a php script to get the images without me being logged in, it probably would supply ALL the images without me being logged in.

But, the amount of effort in securing the script depends upon what is being protected.

You may not care! But just don't rely on that code for being THE most secure script in the world.

The main issue is that I've not tested the imagename value to make sure it is not attempting any nasty directory access.

But, as the image name has to exist as a file AND the file has to be an image AND the file has to be openable, this is probably secure enough.
0
 
mnb93Author Commented:
I don't care about authentication, but other things make up a secure script. eg. Proper Escaping...
0
 
mnb93Author Commented:
And is it just me or have has the font size gotten bigger for EE?
0
 
Richard QuadlingSenior Software DeveloperCommented:
If you are using Firefox, press CTRL+0 (zero). If you are using IE, try View|Text Size|Medium

You probably accidentally increased the font size whilst scrolling (if you have a wheel mouse).

CTRL+WheelDown increases the font size in both IE and FF.
0
 
Richard QuadlingSenior Software DeveloperCommented:
And that REALLY is off topic! But hey! I don't mind! <grin />
0
 
alain34Commented:
to overcome Rquadling isssue about security without using session, I'm using a key that is the MD5 of the image that I have saves in my database.
Two benefits. I'm not saving duplicate image in the database.
It is much more difficult to guess the image name!!!!!
http://www.conceptuel.co.uk/conceptCMS/image.php?id=52ac55a929f3416eec944d0005ee3aa8
0
 
mnb93Author Commented:
I know about the CTRL-0 I did that and I seems that the font on EE is one scrool too high. (After a CTRL-0)
Anyway...
"other things make up a secure script. eg. Proper Escaping..."

I will put in proper authentication...


Also:

"Two benefits. I'm not saving duplicate image in the database.
It is much more difficult to guess the image name!!!!!"

Two filenames can have the same MD5.
0
 
alain34Commented:
No, the MD5 of the binary representation of the image, not the MD5 of the file name, as they aren't any file name if you store the image in a database!!!
0
 
Richard QuadlingSenior Software DeveloperCommented:
Don't store the image in a DB!!!!!

Complete waste of time.

The DB cannot in any way process the "data" that is an image.

Use the disk to store the images as this is the best mechanism to use.

Imagine the SQL server serving up my 23MG of the Orion Nebula to 50 people or more. The amount of memory needed is HUGE! As the ENTIRE image would need to be extracted from the DB, sent to PHP, sent back to the webserver before being sent to the client.

Databases are for DATA.

Images are files. The filesystem is the place to manage files.

Sure, you can use an MD5 hash in a DB to join a hash to a name. Good way of doing things.

0
 
mnb93Author Commented:
Ok, weird I just logged-in and the font changed back to normal...
anyway, lol.... (Back on topic)

How bad would it be to extract the extension from the filename and use that for the MIME? (Yeah.. jpg => JPEG....)
Would that be faster than the other way?

Your thoughts and comments would be helpful.

@alain34 Probably just renaming the images to some random stuff would be better.... but meh...
0
 
mnb93Author Commented:
ohh... what!!! The fonts got bigger again... meh. dw EE is probably screwing round with their Stylesheets.
0
 
mnb93Author Commented:
And it's not me becuase if I navigate to some other site in the same tab, the fonts are normal....
0
 
mnb93Author Commented:
lol, The fonts are normal... (Yeah, I am on the verge of spamming but hey! (Anyone want vergara?))
0
 
mnb93Author Commented:
W00T the fonts stayed this time....
0
 
Richard QuadlingSenior Software DeveloperCommented:
The filename can be junk.

The mime type using getimagesize() is a GUARANTEE.

You should not see any real delay.

The image types that PHP knows about are within the first few bytes of the file.

I would use this.
0
 
Richard QuadlingSenior Software DeveloperCommented:
If you HAVE to provide the file via PHP (rather than just using <img src="somefile.jpg">) then you are not going to get much quicker than the code I provided.

0
 
mnb93Author Commented:
Ahh... beautiful!!!!!!!!!!!!!!! echo 'W'; while(true){echo '0';}echo 'T'; THE FONT IS BACK TO BIG!!! (dw though...)

And thanks for the info.

Steven
0
 
mnb93Author Commented:
BTW now the fonts are normal... (yeah..... I'll stop)
0
 
Richard QuadlingSenior Software DeveloperCommented:
<grin />
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.