Welcome Guest, Not a member yet? Register   Sign In
Caching image requests through PHP - If-Modified-Since not being sent.
#1

[eluser]louis w[/eluser]
Not directly code igniter but I thought I would ask this here to see if anyone can help out since I'm not getting replies elsewhere.

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 sent 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?


Code:
// Get headers sent by the client.
    $headers     = apache_request_headers();
    $file_time    = filemtime($load_path);
    
    log_message('debug', '!! Headers: '.print_r($headers, true));
    
    if (isset($headers['If-Modified-Since']) && (strtotime($headers['If-Modified-Since']) == $file_time)) {
    
        log_message('debug', '!! Doing 304');
    
        // Client's cache IS current, so we just respond '304 Not Modified'.
        header('Last-Modified: '.gmdate('D, d M Y H:i:s', $file_time).' GMT', true, 304);
    
    } else {
    
        log_message('debug', '!! Doing 200');
    
        // 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', $file_time).' GMT', true, 200);
    
        header('Content-Length: '. filesize($file['paths']['server']));
        header('Content-type: '. get_mime_by_extension($load_path));
        readfile($load_path);
        
    }
#2

[eluser]Unknown[/eluser]
I cannot tell you what the difference is, however the code below works for me. Tested on Debian Linux 4.0 with apache2/PHP5.2.

Code:
function get_binary($galleryid, $imageid, $type) /* <== "controller function" */
    {
        if(empty($galleryid) OR !is_numeric($galleryid))
        {
            show_error('Invalid id.');
        }
        
        if(!isset($imageid) OR !is_numeric($imageid))
        {
            show_error('Invalid id.');
        }
        
        if(empty($type))
        {
            show_error('Invalid id.');
        }
        
        /* mimage(model class) used to map (galleryid, imageid [, type]) to an image */

        $mtime = $this->mimage->get_mtime($galleryid, $imageid); /* map to filemtime() */
        $filesize = $this->mimage->get_size($galleryid, $imageid, $type); /* map to filesize() */
        
        $headers = apache_request_headers();
        
        $headers['If-Modified-Since'] = (isset($headers['If-Modified-Since'])) ? $headers['If-Modified-Since'] : 'no-header';
        
        if (strtotime($headers['If-Modified-Since']) == $mtime)
        {
            log_message('info', '!! Doing 304');
            header('Last-Modified: '.gmdate('D, d M Y H:i:s', $mtime).' GMT', true, 304);
        }
        else
        {
            log_message('info', '!! Doing 200');
            header('Last-Modified: '.gmdate('D, d M Y H:i:s', $mtime).' GMT', true, 200);
            header('Content-Length: '. $filesize);
            header('Content-type: image/jpg'); /* I only need jpegs, could be more dynamic */
            
            echo $this->mimage->get_binary($galleryid, $imageid, $type); /* map to readfile() */
        }
    }
#3

[eluser]BrianDHall[/eluser]
That's some pretty nice code - thanks for posting!
#4

[eluser]louis w[/eluser]
I forget what the problem was with my code but I did end up getting it working. I think it may have actually been a testing issue with a firewall.

One addition I added is below. This will let you stream large files instead of having to read them all into memory (which will someone error).


Code:
$handle = fopen($load_path, "rb");
    while (!feof($handle)) {
      echo fread($handle, 8192);
    }
    fclose($handle);




Theme © iAndrew 2016 - Forum software by © MyBB