Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serve image with PHP script vs direct loading an image

Tags:

php

I want to monitor how often some external images are loaded. So my idea is instead of giving a uri directly like this:

www.site.com/image1.jpg

I can create a PHP script which reads the image, so I built a PHP file and my HTML would look like this:

<img src="www.site.com/serveImage.php?img=image1.jpg">

but I don't know how to read the image from disk and return it. Would I return a byte array or set the content type?

Kind regards, Michel

like image 707
Michel Avatar asked Aug 30 '09 13:08

Michel


People also ask

Can you echo an image in PHP?

You cant echo an image using PHP. echo is for strings only. However, you can echo the image source - img src="" Just make sure you put the picture extension at the end of the file you are grabbing.

How can we draw images using PHP?

Draw Lines You can draw a simple straight line between two given points using the imageline($image, $x1, $y1, $x2, $y2, $color) function. The $image parameter is an image resource that will have been created earlier using functions like imagecreatetruecolor() or imagecreatefromjpeg() .


3 Answers

Sending images through a script is nice for other things like resizing and caching on demand.

As answered by Pascal MARTIN the function readfile and these headers are the requirements:

  • Content-Type
    • The mime type of this content
    • Example: header('Content-Type: image/gif');
    • See the function mime_content_type
    • Types
      • image/gif
      • image/jpeg
      • image/png

But beside the obvious content-type you should also look at other headers such as:

  • Content-Length
    • The length of the response body in octets (8-bit bytes)
    • Example: header('Content-Length: 348');
    • See the function filesize
    • Allows the connectio to be better used.
  • Last-Modified
    • The last modified date for the requested object, in RFC 2822 format
    • Example: header('Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT');
    • See the function filemtime and date to format it into the required RFC 2822 format
      • Example: header('Last-Modified: '.date(DATE_RFC2822, filemtime($filename)));
    • You can exit the script after sending a 304 if the file modified time is the same.
  • status code
    • Example: header("HTTP/1.1 304 Not Modified");
    • you can exit now and not send the image one more time

For last modified time, look for this in $_SERVER

  • If-Modified-Since
    • Allows a 304 Not Modified to be returned if content is unchanged
    • Example: If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
    • Is in $_SERVER with the key http_if_modified_since

List of HTTP header responses

like image 95
OIS Avatar answered Oct 22 '22 14:10

OIS


To achieve something like this, your script will need to :

  • send the right headers, which depend on the type of the image : image/gif, image/png, image/jpeg, ...
  • send the data of the image
  • making sure nothing else is sent (no white space, no nothing)

This is done with the header function, with some code like this :

header("Content-type: image/gif");

Or

header("Content-type: image/jpeg");

or whatever, depending on the type of the image.


To send the data of the image, you can use the readfile function :

Reads a file and writes it to the output buffer.

This way, in one function, you both read the file, and output its content.


As a sidenote :

  • you must put some security in place, to ensure users can't request anything they want via your script : you must make sure it only serves images, from the directory you expect ; nothing like serveImage.php?file=/etc/passwd should be OK, for instance.
  • If you're just willing to get the number of times a file was loaded each day, parsing Apache's log file might be a good idea (via a batch run by cron each day at 00:05, that parses the log of the day before, for instance) ; you won't have real-time statistics, but it will require less resources on your server (no PHP to serve static files)
like image 28
Pascal MARTIN Avatar answered Oct 22 '22 14:10

Pascal MARTIN


I use the "passthru" function to call "cat" command, like this:

header('Content-type: image/jpeg');
passthru('cat /path/to/image/file.jpg');

Works on Linux. Saves resources.

like image 20
J. Bruni Avatar answered Oct 22 '22 13:10

J. Bruni