Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caching image requests through PHP - If-Modified-Since not being sent

I am serving images through php and having some problems setting it up to respond with 304 headers to save on load time.

Most of the code below I found on php.net. It works, however ALWAYS responds with 200. For some reason the If-Modified-Since header is not being received on any requests even though I am sending the Last-Modified header initially. This is being done on an apache server. Any idea what might be wrong?

Example here.

This page will load the image from disk and display it to browser, along with sending a Last-Modified header. If you refresh the page, the browser doesn't send a If-Modified-Since header like it should.

define('SITEPATH', (dirname($_SERVER['SCRIPT_NAME']) == '/') ? '/' : dirname($_SERVER['SCRIPT_NAME']).'/');

$load_path = $_SERVER['DOCUMENT_ROOT'] . SITEPATH . 'fpo_image.jpg';

// Get headers sent by the client.
$headers    = apache_request_headers(); 
$file_time  = filemtime($load_path);

header('Cache-Control: must-revalidate');
header('Last-Modified: '.gmdate('D, d M Y H:i:s', $file_time).' GMT');

if (isset($headers['If-Modified-Since']) && (strtotime($headers['If-Modified-Since']) == $file_time)) {

    header('HTTP/1.1 304 Not Modified');
    header('Connection: close');

} else {

    header('HTTP/1.1 200 OK');
    header('Content-Length: '. filesize($load_path));
    header('Content-type: image/jpeg');                         

    readfile($load_path);

}
like image 436
Louis W Avatar asked Jun 24 '09 14:06

Louis W


1 Answers

mandor at mandor dot net posted a solution at the PHP.net documentation for the header function which worked for me:

<?php

        // Test image.
        $fn = '/test/foo.png';

        // Getting headers sent by the client.
        $headers = apache_request_headers();

        // Checking if the client is validating his cache and if it is current.
        if (isset($headers['If-Modified-Since']) && (strtotime($headers['If-Modified-Since']) == filemtime($fn))) {
            // Client's cache IS current, so we just respond '304 Not Modified'.
            header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($fn)).' GMT', true, 304);
        } else {
            // Image not cached or cache outdated, we respond '200 OK' and output the image.
            header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($fn)).' GMT', true, 200);
            header('Content-Length: '.filesize($fn));
            header('Content-Type: image/png');
            print file_get_contents($fn);
        }

    ?>
like image 66
Keith Hughitt Avatar answered Oct 06 '22 22:10

Keith Hughitt