Serve image with PHP script vs direct loading an image
Solution 1:
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
anddate
to format it into the required RFC 2822 format- Example:
header('Last-Modified: '.date(DATE_RFC2822, filemtime($filename)));
- Example:
- 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
- Example:
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 keyhttp_if_modified_since
List of HTTP header responses
Solution 2:
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)
Solution 3:
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.
Solution 4:
You must set the content type:
header("Content-type: image/jpeg");
Then you load the image and output it like this:
$image=imagecreatefromjpeg($_GET['img']);
imagejpeg($image);