An in depth analysis of PHP and browser caching

  • 2020-06-07 04:03:34
  • OfStack

We tend to optimize our cache Settings on the server, but we pay little attention to the client-side cache, specifically the browser's cache mechanism.
Every browser has a caching policy that temporarily caches every file you browse into a special folder. When the user repeatedly submits a page request, we can tell the user that the page has not changed and the cache can be invoked. So how do we know if the user has cached data for this page? Instead, the browser sends the http header first, like this:
Date: Sun, 30 Jul 2006 09:18:11 GMT
Content-Type: image/gif
Last-Modified: Wed, 19 Jul 2006 07:40:06 GMT
ETag: "8c55da8d6abc61:2327"
Content-Length: 14757
Among them
Last-Modified: Wed, 19 Jul 2006 07:40:06 GMT
ETag: "8c55da8d6abc61:2327"
This is the cached information about the page. The browser then reads the data from the cache if the server returns a response code of 304 instead of HTTP 200 (OK).
// Tell the client browser not to use cache, HTTP 1.1 protocol
header("Cache-Control: no-cache, must-revalidate");

// Tell the client browser not to use caching and to be compatible with HTTP 1.0
header("Pragma: no-cache");
According to this principle, it can be used in pages that are not updated frequently or need to be refreshed frequently, which can greatly reduce the burden on the server, because if it finds that the client has a cache, it will send 1 304 response to the client and then stop the execution of the program.

Contained in the request from the browser If - Modified - Since and If None - Match two parameters, first the last modification time is Thu ask data, 19 Jun 2008 16:24:01 GMT then the server will check the data, last modified time, if it is the time to return the status code 304 (without modification), when the browser at this time received the status code is 304, he won't download data but the call from the local cache storage. However, the browser will only send the ES41en-ES42en-ES43en parameter with the value of ES44en-ES45en returned from the previous server when data for the requested resource is present in the local cache (not all servers support ES46en-ES47en-ES48en and ES49en-ES50en-ES51en); If-None-Match has a similar function. It is generated by the value of Etag returned by the server. It can be any value, as it only makes the server check the modification time of the data and then go back, as long as it is not none (the default value) or null.

So we can set the value of Etag returned to the browser in the first part of the code, and then when the resource is requested the second time there will be an ES60en-ES61en-ES62en argument attached to it. By verifying that the value is actually the Etag value issued, we can specify that the server returns to 304 and force the exit. If-Modified-Since is the same as php (Last-ES70en is very common for setting cache timeouts and so on).
Copy the PHP code to the clipboard

    if ($_SERVER["HTTP_IF_NONE_MATCH"] == "claymorephp.com")
    {
        header('Etag:'.'zhaiyun.com',true,304);
        exit();
    }
    else {
        header('Etag:'."claymorephp.com");
    }
     You can change it a little bit 1 Bottom: 
    $expires=date("Ymd"); //1 Day after cache expiration 
    if ($_SERVER["HTTP_IF_NONE_MATCH"] == $expires)
    {
        header('Etag:'.$expires,true,304);
        exit();
    }
    else {
        header('Etag:'.$expires);
    }
if ($_SERVER["HTTP_IF_NONE_MATCH"] == "claymorephp.com") { header('Etag:'.'zhaiyun.com',true,304); exit(); } else { header('Etag:'."claymorephp.com"); }  You can change it a little bit 1 Bottom:  $expires=date("Ymd"); //1 Day after cache expiration  if ($_SERVER["HTTP_IF_NONE_MATCH"] == $expires) { header('Etag:'.$expires,true,304); exit(); } else { header('Etag:'.$expires); } 

In addition, when GZIP and ETAG are used at the same time, there will be a problem, that is, ETAG has no value. This problem is common. I have not found the relevant reason for the moment.
For the above reasons, the client cache for PHPBLOG is processed down (both HTTP_IF_NONE_MATCH and HTTP_IF_MODIFIED_SINCE are judged) :
Copy the PHP code to the clipboard

      if($_SERVER['HTTP_IF_NONE_MATCH'])
        {
            if($_SERVER['HTTP_IF_NONE_MATCH'] == 'phpblog')
            {
                header('Etag:phpblog',true,304);// Control browser cache 
                $_SESSION['time_end']=microtime(true);
                exit();
            }
        }
        else if($_SERVER['HTTP_IF_MODIFIED_SINCE'])//eg:Sun, 02 Nov 2008 07:08:25 GMT; length=35849
        {
            $array=explode(' ',$_SERVER['HTTP_IF_MODIFIED_SINCE']);
            $gmday=$array[1];
            $month_array=array(
            "Jan"=>"01",
            "Feb"=>"02",
            "Mar"=>"03",
            "Apr"=>"04",
            "May"=>"05",
            "Jun"=>"06",
            "Jul"=>"07",
            "Aug"=>"08",
            "Sep"=>"09",
            "Oct"=>"10",
            "Nov"=>"11",
            "Dec"=>"12");
            $gmmonth=$month_array[$array[2]];
            $gmyear=$array[3];
            $array=explode(':',$array[4]);
            $gmtimestamp=gmmktime($array[0],$array[1],$array[2],$gmmonth,$gmday,$gmyear);
            if(gmmktime()-$gmtimestamp<$config_client_cache_time*60*60)
            {
                header('Etag:phpblog',true,304);// Control browser cache 
                $_SESSION['time_end']=microtime(true);
                exit();
            }
        }
if($_SERVER['HTTP_IF_NONE_MATCH']) { if($_SERVER['HTTP_IF_NONE_MATCH'] == 'phpblog') { header('Etag:phpblog',true,304);// Control browser cache  $_SESSION['time_end']=microtime(true); exit(); } } else if($_SERVER['HTTP_IF_MODIFIED_SINCE'])//eg:Sun, 02 Nov 2008 07:08:25 GMT; length=35849 { $array=explode(' ',$_SERVER['HTTP_IF_MODIFIED_SINCE']); $gmday=$array[1]; $month_array=array( "Jan"=>"01", "Feb"=>"02", "Mar"=>"03", "Apr"=>"04", "May"=>"05", "Jun"=>"06", "Jul"=>"07", "Aug"=>"08", "Sep"=>"09", "Oct"=>"10", "Nov"=>"11", "Dec"=>"12"); $gmmonth=$month_array[$array[2]]; $gmyear=$array[3]; $array=explode(':',$array[4]); $gmtimestamp=gmmktime($array[0],$array[1],$array[2],$gmmonth,$gmday,$gmyear); if(gmmktime()-$gmtimestamp<$config_client_cache_time*60*60) { header('Etag:phpblog',true,304);// Control browser cache  $_SESSION['time_end']=microtime(true); exit(); } } 

Cached HEADER is sent like this:
Copy the PHP code to the clipboard

     $client_cache_time=$config_client_cache_time*60*60;// unit  -  seconds 
            header('Cache-Control: public, max-age='.$client_cache_time);
            header('Expires: '.gmdate('D, d M Y H:i:s',time()+$client_cache_time).' GMT');// Set the page cache time 
            header('Last-Modified: '.gmdate('D, d M Y H:i:s',time()).' GMT');// Returns the last modification time 
            header('Pragma: public');
            header('Etag:phpblog');// Returns an identity used to indicate that it was actually accessed last time ( A cache exists in the browser )
$client_cache_time=$config_client_cache_time*60*60;// unit  -  seconds  header('Cache-Control: public, max-age='.$client_cache_time); header('Expires: '.gmdate('D, d M Y H:i:s',time()+$client_cache_time).' GMT');// Set the page cache time  header('Last-Modified: '.gmdate('D, d M Y H:i:s',time()).' GMT');// Returns the last modification time  header('Pragma: public'); header('Etag:phpblog');// Returns an identity used to indicate that it was actually accessed last time ( A cache exists in the browser )


Related articles: