Handling If-modified-since header in a PHP-script
This is definitely possible in PHP!
When the browser checks if there were modifications, it sends an If-Modified-Since
header; in PHP this value would be set inside $_SERVER['HTTP_IF_MODIFIED_SINCE']
.
To decode the date/time value (encoded using rfc822 I believe), you can just use strtotime()
, so:
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) &&
strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= filemtime($localFileName))
{
header('HTTP/1.0 304 Not Modified');
exit;
}
Explanation: if the If-Modified-Since
header is sent by the browser AND the date/time is at least the modified date of the file you're serving, you write the "304 Not Modified" header and stop.
Otherwise, the script continues as per normal.
How to test for If-Modified-Since HTTP Header support
I have performed some testing on this and it appears to work as follows;
If you send an If-Modified-Since header with a date that is in the past (5 mins previous to the current time should do it) then sites such as google.com, w3.org, mattcutts.com will return a "HTTP/1.1 304 Not Modified" header. Sites such as yahoo.com, bbc.co.uk and stackoverflow.com always return a "HTTP/1.1 200 OK".
The "Last-Modified" header has nothing to do with "If-Modified-Since" because the whole point of sending back a "HTTP/1.1 304 Not Modified" header is that you don't have to send the body with it (thus saving bandwidth - which is the whole point behind this).
Therefore, the answer to my question is that if a site doesn't return a "HTTP/1.1 304 Not Modified" header when you send an "If-Modified-Since 5 mins ago" header, the site doesn't support the "If-Modified-Since" request properly.
If I am incorrect, please say so and provide testing to show.
Edit: I forgot to add that a good test is to make a normal HEAD request to the domain (e.g. w3.org), grab the "Last Modified" date and then make another request with "If-Modified-Since:". This will test that both the "Last Modified" value and "If-Modified-Since" request are supported. Please Note: just because the server sends back a "Last Modified" date doesn't mean it supports "If-Modified-Since"
If Modified Since Header in WordPress
the_modified_date()
is a template tag that must used inside the loop, that is why it is not wokring for you.
WordPress provide a action and filter hook to include or modify HTTP headers:
send_headers
actionwp_headers
filter (I don't find reference in codex)
But it doesn't work for this purpose. For example, the next code is not working:
add_action( 'send_headers', 'cyb_add_last_modified_header' );
function cyb_add_last_modified_header() {
//Check if we are in a single post of any type (archive pages has not modified date)
if( is_singular() ) {
$post_id = get_queried_object_id();
if( $post_id ) {
header("Last-Modified: " . get_the_modified_time("D, d M Y H:i:s", $post_id) );
}
}
}
Why?
The main wp query is not build at this moment, neither in wp_headers
filter. So, is_singular()
returns false
, get_queried_object_id()
returns NULL
and there is no way to get the modified time of the current post.
A posible solution is to use template_redirect
action hook, as suggested by Otto in this question (tested and working):
add_action('template_redirect', 'cyb_add_last_modified_header');
function cyb_add_last_modified_header($headers) {
//Check if we are in a single post of any type (archive pages has not modified date)
if( is_singular() ) {
$post_id = get_queried_object_id();
if( $post_id ) {
header("Last-Modified: " . get_the_modified_time("D, d M Y H:i:s", $post_id) );
}
}
}
Please Note
The question is answered by @cybmeta at here. I'm just sharing the answer here so that if anyone is looking for the answer here, he/she will find it. All credit goes to @cybmeta.
Caching image requests through PHP - If-Modified-Since not being sent
I believe it should be
if (isset($headers['If-Modified-Since']) && (strtotime($headers['If-Modified-Since']) >= $file_time)) {
Checking if the modified time is greater than or equal rather than just equal. Although I do understand the two values should be the same.
Answering HTTP_IF_MODIFIED_SINCE and HTTP_IF_NONE_MATCH in PHP
I've always used:
function caching_headers ($file, $timestamp) {
$gmt_mtime = gmdate('r', $timestamp);
header('ETag: "'.md5($timestamp.$file).'"');
header('Last-Modified: '.$gmt_mtime);
header('Cache-Control: public');
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
if ($_SERVER['HTTP_IF_MODIFIED_SINCE'] == $gmt_mtime || str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])) == md5($timestamp.$file)) {
header('HTTP/1.1 304 Not Modified');
exit();
}
}
}
Don't remember whether I wrote it or got it from somewhere else...
I'm normally using it at the top of a file in this way:
caching_headers ($_SERVER['SCRIPT_FILENAME'], filemtime($_SERVER['SCRIPT_FILENAME']));
Related Topics
Dynamically Changing Image Colours
Detect If Android App Has Been Installed on the Device Using a Mobile Web Page - PHP and Js
MySQL - Insert Date Range into Date Columns If Dates Don't Overlap with Existing Ones
Ruby and PHP Hmacs Not Agreeing
Preg_Match Equivalent in Swift
Swift Sync Data of Core Data an MySQL Database
Using Variables in MySQL Update (Php/Mysql)
Filling Gaps in Dates Returned from Database - Pure SQL Solution Possible
Performance in Pdo/Php/Mysql: Transaction Versus Direct Execution
Access Joomla 2.5 from External Script to Get Article by Id
Looping Through Query Results Multiple Times with MySQLi_Fetch_Array
Getting All Values from H1 Tags Using PHP
Dynamically Generating a Qr Code with PHP
In PHP Can Someone Explain Cloning VS Pointer Reference
Reflectionexception: Class Classname Does Not Exist - Laravel