Schnulla Posted November 8, 2008 Share Posted November 8, 2008 Hello forum, I have the following code to deliver ALL of my website graphics including the jpg/png files for the interface: if (($FileInfos= stat($File)) or die("File not found!")); $FileExt= substr($File, -3); // no need to check for >3 cause I always append a path ;-) $FileTypeMIME= array("jpg" => "image/jpeg", "png" => "image/png", "gif" => "image/gif", "ico" => "image/x-icon"); $ContentType= $FileTypeMIME[$FileExt]; if (empty($ContentType)) die("You are not allowed to access this file!"); header("Content-Type: " . $ContentType); header("Content-Length: " . $FileInfos[7]); header("Content-Disposition: filename=" . basename($File)); header("Last-Modified: " . gmdate("D, d M Y H:i:s", $FileInfos[9]) . ' GMT'); readfile($File); But I have the feeling that the images are not cached on client side so if I load the same page twice it looks a little bit as if the images are received again from server. I'm new to php btw. Shouldn't the images be in cache so that the browser only compares the Last-Modified header field and then stops receiving data? Or is it just stupid from me to think so and I should not deliver the interface graphics via php (readFile). Thanks! Quote Link to comment https://forums.phpfreaks.com/topic/131864-readfile-image-caching-on-client-side/ Share on other sites More sharing options...
Schnulla Posted November 9, 2008 Author Share Posted November 9, 2008 Thanks for no-answer.... Anyway I found a 2 step solution and hope it is useful for someone who is reading this: 1. Tell the client to cache the image when sending the image: header('Cache-Control: public, must-revalidate, max-age=3600'); // 1 hour 2. If the client requests the image again: // Getting headers sent by the client. $ClientHeaders= apache_request_headers(); // Checking if the client is validating his cache and if it is current. if (isset($ClientHeaders["If-Modified-Since"]) && (strtotime($ClientHeaders["If-Modified-Since"]) == $FileInfos[9])) { // Client's cache IS current, so we just respond '304 Not Modified'. header("Last-Modified: " . gmdate("D, d M Y H:i:s", $FileInfos[9]) . " GMT", true, 304); } else { // Image not cached or cache outdated, we respond '200 OK' and output the image. header('Cache-Control: public, must-revalidate, max-age=3600'); header("Last-Modified: " . gmdate("D, d M Y H:i:s", $FileInfos[9]) . " GMT", true, 200); header("Content-Type: " . $ContentType); header("Content-Length: " . $FileInfos[7]); header("Content-Disposition: filename=" . basename($File)); readfile($File); } Quote Link to comment https://forums.phpfreaks.com/topic/131864-readfile-image-caching-on-client-side/#findComment-686011 Share on other sites More sharing options...
Schnulla Posted November 9, 2008 Author Share Posted November 9, 2008 CORRECTION: You must also send the cache directive in the 304 response to make it work! // Getting headers sent by the client. $ClientHeaders= apache_request_headers(); // Checking if the client is validating his cache and if it is current. if (isset($ClientHeaders["If-Modified-Since"]) && (strtotime($ClientHeaders["If-Modified-Since"]) == $FileInfos[9])) { // Client's cache IS current, so we just respond '304 Not Modified'. header('Cache-Control: public, must-revalidate, max-age=3600'); header("Last-Modified: " . gmdate("D, d M Y H:i:s", $FileInfos[9]) . " GMT", true, 304); } else { // Image not cached or cache outdated, we respond '200 OK' and output the image. header('Cache-Control: public, must-revalidate, max-age=3600'); header("Last-Modified: " . gmdate("D, d M Y H:i:s", $FileInfos[9]) . " GMT", true, 200); header("Content-Type: " . $ContentType); header("Content-Length: " . $FileInfos[7]); header("Content-Disposition: filename=" . basename($File)); readfile($File); } Quote Link to comment https://forums.phpfreaks.com/topic/131864-readfile-image-caching-on-client-side/#findComment-686074 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.