ChatGPT解决这个技术问题 Extra ChatGPT

How to prevent Browser cache for php site

I have a php site running in cloud server.When ever i add new files css, js or images the browser is loading the same old js, css and image files stored in cache.

My site has a doctype and meta tag as below

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <meta http-equiv="Page-Enter" content="blendTrans(Duration=1.0)">
  <meta http-equiv="Page-Exit" content="blendTrans(Duration=1.0)">
  <meta http-equiv="Site-Enter" content="blendTrans(Duration=1.0)">
  <meta http-equiv="Site-Exit" content="blendTrans(Duration=1.0)">

Because of the above doctype and meta code am i loading the same files cached in browser instead of new one

No Cache in all Browsers. You can also do a ?randomGeneratedNumber on the files you dont want to be cached.
You probably don't want to disable cache completely for images /js / css: stackoverflow.com/questions/4206224/…
Resisted the temptation to necro, but please, anyone considering this: stop. Learn to control and use caching, don't just blindly disable it because of one inconvenient episode. Read the chapter on Caching from HTTP The Definitive Guide — this book (and the RFCs) ought to be mandatory reading, with a test. Learn how to specify the Last-Modified, respond to If-Modified-Since, and utilize ETag identification. Then when the asset is updated, browsers will be informed when that 304 becomes a 200 once more.
"inconvenient episode" in 99.999999999999999999999999999% of requests.

C
Codesen

try this

<?php

header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
?>

Except for "max-age=0", those are the headers sent by PHP without specifying the above in my installation.. It seems PHP tries to prevent browser caching by default...
I have a WordPress plugin that sends an alternate theme to old versions of Internet Explorer and it was getting badly tripped up on some caching systems. This post came up on my first Google search. Well played.
Do keep in mind that this cannot be embedded inside of html; this should be at the very top of the page.
Note: If you use session_start() afterwards, it will overwrite your header with Cache-Control: private, max-age=10800, pre-check=10800 because 180 minutes is the default value of session.cache_expire. If you can not avoid starting the session, but you need to disable the cache use session_cache_limiter('private');session_cache_expire(0);.
@thdoan The second parameter of header function is a boolean for replace. The optional replace parameter indicates whether the header should replace a previous similar header, or add a second header of the same type.
R
Ritesh Aryal

Here, if you want to control it through HTML: do like below Option 1:

<meta http-equiv="expires" content="Sun, 01 Jan 2014 00:00:00 GMT"/>
<meta http-equiv="pragma" content="no-cache" />

And if you want to control it through PHP: do it like below Option 2:

header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', FALSE);
header('Pragma: no-cache');

AND Option 2 IS ALWAYS BETTER in order to avoid proxy based caching issue.


A
Aakanksha

You can try this:

    header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");
    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
    header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
    header("Cache-Control: post-check=0, pre-check=0", false);
    header("Pragma: no-cache");
    header("Connection: close");

Hopefully it will help prevent Cache, if any!


This only pertains to the caching of the HTML files right? And has nothing to do with eTag? Thanks!
just the first line should suffice perfectly. 5th line is actually plain wrong and has nothing to do in a server response (it is a request header). sixth line will have no effect whatsovever. i could go on...
The shotgun approach: throw everything at the wall, hope something sticks. As per my comment on the question itself, I can highly recommend grabbing a copy of HTTP: The Definitive Guide and reading the chapter on Caching. Also the RFCs, but reading those is a distinct skill. ("Connection: close" is a hilarious foot-shot to include, disabling efficient pipelining of requests, or will do nothing, but I suspect PHP might actually let that through.)
L
Lukas

I had problem with caching my css files. Setting headers in PHP didn't help me (perhaps because the headers would need to be set in the stylesheet file instead of the page linking to it?).

I found the solution on this page: https://css-tricks.com/can-we-prevent-css-caching/

The solution:

Append timestamp as the query part of the URI for the linked file. (Can be used for css, js, images etc.)

For development:

<link rel="stylesheet" href="style.css?<?php echo date('Y-m-d_H:i:s'); ?>">

For production (where caching is mostly a good thing):

<link rel="stylesheet" type="text/css" href="style.css?version=3.2">
(and rewrite manually when it is required)

Or combination of these two:

<?php
    define( "DEBUGGING", true ); // or false in production enviroment
?>
<!-- ... -->
<link rel="stylesheet" type="text/css" href="style.css?version=3.2<?php echo (DEBUGGING) ? date('_Y-m-d_H:i:s') : ""; ?>">

EDIT:

Or prettier combination of those two:

<?php
    // Init
    define( "DEBUGGING", true ); // or false in production enviroment
    // Functions
    function get_cache_prevent_string( $always = false ) {
        return (DEBUGGING || $always) ? date('_Y-m-d_H:i:s') : "";
    }
?>
<!-- ... -->
<link rel="stylesheet" type="text/css" href="style.css?version=3.2<?php echo get_cache_prevent_string(); ?>">

Arbitrary versions, current timestamps (defeating caching entirely)… but not the one thing that actually makes sense and work, regardless of a "debugging" flag or not. Why aren't you using the actual mtime of the file? Then you'd literally never need to update the PHP, and caches wouldn't become completely and fantastically useless. Or just deliver your statics with a properly configured HTTP server like Nginx or Apache that sets a proper Last-Modified and ETag. Similarly, that type of "debugging" flag already exists… in the browser. (Disable caches, refresh without cache, empty caches, …)
i
ismavolk

Prevent browser cache is not a good idea depending on the case. Looking for a solution I found solutions like this:

<link rel="stylesheet" type="text/css" href="meu.css?v=<?=filemtime($file);?>">

the problem here is that if the file is overwritten during an update on the server, which is my scenario, the cache is ignored because timestamp is modified even the content of the file is the same.

I use this solution to force browser to download assets only if its content is modified:

<link rel="stylesheet" type="text/css" href="meu.css?v=<?=hash_file('md5', $file);?>">

Yikes! This would be terrible for performance and scalability to always be loading all of your CSS/JS files in the main thread to check their size/hash.
@Dalin Before you cry the tears of Gentoo ricer (a Linux distro known for "going fast" by being excessively compiled from source and architecture-tuned) I'd clock a stat call. Without filesystem cache, 16ns, tops? With cache, reliably < 8ns. Nanoseconds. And on my system MD5 can process 754 MiB/s without blinking. (openssl speed md5) Combined, a 100KB CSS file would have a combined additional overhead of… 129µs (microseconds, 0.1295ms) + 8ns (which does not meaningfully contribute to the final number) = 129µs.
Upon further consideration, it blows me over that the only "correct" answer (with lowest maintenance burden, most accurate/reliable behavior) is both the least voted for, and dismissed in a single comment on such flimsy and unrealistic grounds.
You and I probably work on different websites. But I stand by my comment. If there's dozen's of concurrent threads delivering web pages at any point in time, then I think there's better options that you won't even need to question whether it's scalable. hash_file('md5', $deployment_counter) or hash_file('md5', $cache_clear_counter) are the first that come to mind.
@Dalin So… streaming the entire file from disk (eventually kernel VFS cache) to re-hash it on every access? Even if the mtime has not changed? "In before" a hash cache gets thrown into this "solution"… only stepping further away from HTTP standard caching mechanisms. I know I mentioned hashing, but it's absolutely excessive. Refer to §7 (Caching) and, for specific details, refer to §1.8.2, §3.5.1.1, §3.5.4.2, §13.4.5, §17.4.1, and §20.6 through §20.10 of HTTP: The Definitive Guide. It is a remarkably good reference.
E
Emre Pişirici

You can also use query string to your cached files. It will not affect to neither behaviour of your style nor js files.

For example:

example.com/mystyle.css -> 
example.com/mystyle.css?<?php echo random(1000, 5000); ?>

关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now