<?php
class HttpCacheFilter extends CFilter
{
/**
* Timestamp for the last modification date. Must be a string parsable by {@link http://php.net/DateTime DateTime}.
* @var string
*/
public $lastModified;
/**
* Seed for the ETag. Can be anything that passes through {@link http://php.net/serialize serialize()}.
* @var mixed
*/
public $etagSeed;
public function preFilter($filterChain)
{
if($this->lastModified && $lastModified=new DateTime($this->lastModified))
{
if(key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER) && $lastModified->diff(new DateTime($_SERVER['HTTP_IF_MODIFIED_SINCE']))->format('r')!='+')
{
$this->send304();
return false;
}
header('Last-Modified: '.$lastModified->format('r'));
}
else if($this->etagSeed)
{
$etag='"'.base64_encode(hash('ripemd160', serialize($this->etagSeed), true)).'"';
if(key_exists('HTTP_IF_NONE_MATCH', $_SERVER) && $_SERVER['HTTP_IF_NONE_MATCH']==$etag)
{
$this->send304();
return false;
}
header('ETag: '.$etag);
}
header('Cache-Control: must-revalidate, proxy-revalidate, private');
return true;
}
/**
* Send the 304 HTTP status code to the client
*/
private function send304()
{
header($_SERVER['SERVER_PROTOCOL'].' 304 Not modified');
}
}This filter can be used quite similar to COutputCache (See the guide on filters for more). Last-Modified is favoured over ETags for SEO reasons. I decided not to use both at once since that would add unnecessary overhead: According to the RFCs, a client would have to check both.

Help





















