How to Get the Browser to Cache Images, with PHP

How to get the browser to cache images, with PHP?

If you are using php to check if the user is logged in before outputting the message, then you don't want the browser to cache the image.

The entire point of caching is to call the server once and then never call it again. If the browser caches the image, it won't call the server and your script won't run. Instead, the browser will pull your image from cache and display it, even if the user is no longer logged in. This could potentially be a very big security hole.

Caching images in browser with URL parameters and XSendFile

I think this is a duplicate.

But since there is a bounty lets try to adapt your code together with the suggested solution there.

You need to check that Apache has mod_expires and mod_headers enabled and working properly.

And then before you start real output check if file was modified:

...
$last_modified_time = filemtime($file);
$etag = md5_file($file);
// always send headers
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT");
header("Etag: $etag");
// exit if not modified
if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time ||
@trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) {
header("HTTP/1.1 304 Not Modified");
exit;
} else {
header("X-Sendfile: $file");
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
}

Prevent browser from caching images

Try putting a random variable on the end of the url

http://www.test.com/images/123.jpg?{{rand()}}

Image generated with PHP caching

There are a few options, depending on your situation. If "images/image.png" is an actual file on the server and you are accessing it directly, then you have to change the cache settings on the folder or use .htaccess to inform a browser to resend it.

<FilesMatch "\.(ico¦pdf¦flv¦jpg¦jpeg¦png¦gif¦js¦css¦swf)$">
ExpiresDefault A604800
Header set cache-control: "no-cache, public, must-revalidate"
</FilesMatch>

If you are using PHP to find the image and returning it, you can use PHP to send headers.

header("Expires: ".gmdate("D, d M Y H:i:s", time()+1800)." GMT");
header("Cache-Control: max-age=1800");

To do it perfectly with PHP, you can check if its actually modified

$last_modified_time = @filemtime($file);
header("Expires: ".gmdate("D, d M Y H:i:s", $last_modified_time+1800)." GMT");
//change with $last_modified_time instead of time().
//Else if you request it 29mins after it was first created, you still have to wait 30mins
//but the image is recreated after 1 min.

header("Cache-Control: max-age=1800");
header("Vary: Accept-Encoding");

// exit if not modified
if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER)) {
if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time) {
header("HTTP/1.1 304 Not Modified");
return;
}
}

Cache AND display images php

I think this is what you looking for:

<?php

if(empty($_GET['user_id']) || !preg_match( '/^[0-9]+$/' , $_GET['user_id'])){
header( '400 Bad Request' );
exit(1);
}

include_once "DBH.php";

$user_id = intval( $_GET['user_id'] );

$result = $conn->query("SELECT image FROM profilePictures WHERE user_id = $user_id");
if($result->num_rows == 0){
// Not Found
header('404 Not Found');
exit(1);
}

$imgData = $result->fetch_assoc();
header("Content-type: image");
$cache_for = 3600; // One hour in seconds
$cache_until = gmdate("D, d M Y H:i:s", time() + $cache_for) . " GMT";
header("Expires: $cache_until");
header("Pragma: cache");
header("Cache-Control: max-age=$cache_for");
echo $imgData['image'];
exit(0);

Comments

First I checked if the user_id is supplied in the request, if so then check if it was a valid number if it doesn't then respond with a 400 error.

And also I have removed a SQLi in your code src='displayProfilePicture.php?user_id=-1 or 1=1.

And I have set the caching headers, so the browser will cache the image for an hour.

How to prevent browser image caching?

Just put a random parameter at the end of the image URL. A timestamp can also be used very well for this.

For example in PHP:

"http://domain.com/img.png?t=" . time();

The browser will always load this image new. You should use it with care though, it will make loading times slower.

Browser Caching of images and videos served via php query strings

Thanks @tim!

The problem was in the headers i was serving alongside my media. I looked at the response in Chrome and it said:

Cache-Control: must-revalidate, no-cache, no-store

I didn't set these, it must be a default of apache since I'm serving through a script? Anyways, to fix, I just added:

Cache-Control: public

to my PHP file and it seems to be working!

How to browser cache image from php

You could modify your imgtag.php file, so it sends that header, using the PHP header() function :

header('Cache-Control: max-age=2592000');

Note : setting headers must be done before any output.

Do browsers cache images?

Yes the browser will cache them, often even when your headers say otherwise. I have found the best combination is to issue the necessary Cache-Control headers along with appending a random string to the source URL.

Example, set the max age in seconds:

header("Cache-Control: max-age=3600");

Then append a random string to your img sources. This will need to be in Javascript, not in PHP because once your URLs are generated in PHP they won't keep updating with a new random string:

var randomString = "" + new Date().getTime();
var imageUrl = yourImageArray[someIndex] + "?" + randomString;

Hope you get the idea.



Related Topics



Leave a reply



Submit