La classe propose une compression des fichiers de cache via la fonction gzcompress.
Edit : La gestion du temps de validité du cache serveur est ajoutée. Une classe pour gérer le cache client (via headers HTTP) est ajoutée aussi.
Exemple d'utilisation :
<?php
//On initialise le cache client
$cacheHTTP = new LambdaHTTPCache();
//On va afficher une page qui varie selon l'utilisateur, on initialise donc le cache serveur propre à l'utilisateur
$cache = new LambdaCache('cache_'.$_SESSION['username'].'.php');
//On indique au cache client que la page envoyée sera personnelle (pour les proxies)
$cacheHTTP -> setProxy(TRUE, FALSE);
//On indique au cache client la date de dernière modification du fichier de cache serveur
$cacheHTTP -> checkTime($cache -> lastModified());
//On envoie les headers HTTP
$cacheHTTP -> sendHeaders();
//On recalcule la page si la méthode show() ne renvoit rien (sinon elle aura affiché le contenu du cache serveur)
if (!$cache -> show())
{
echo 'Blablabla...';
$cache -> close(); //On écrit le fichier cache et on affiche le résultat
}
?>
Code source des deux classes :
<?php
/*
Lambda System - by Klomac ([email protected])
LambdaCache : This class allows the user to call a cache file or to create it if it doesn't exist yet.
LambdaHTTPCache : This class send the appropriate HTTP headers to use the client cache.
-----------------------------GNU GPL--------------------------------------
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
---------------------------------------------------------------------------
*/
class LambdaCache
{
private $cacheFile; //The cache filename
private $cachePath; //The cache full path
private $compressData; //Define if the gz compression must be used or not
private $cacheContents; //The content of the cache file
private $cacheExists = FALSE; //Indicate if the cache file exists or not
private $timeLimit;
//The errors which may be displayed
private $errors = array(
'Unable to write the cache file',
'Unable to create the cache directory');
public static $cacheDir; //The directory which contains the cache files (must be set by the user)
public $gzLevel = 1; //The level of the gz compression (better is 1, worst is 9)
//Magical methods
public function __construct ($filename, $timeLimit = FALSE, $cacheDir = 'cache/', $compression = TRUE)
{
//We set up the main variables
$this -> cacheFile = $filename;
$this -> cacheDir = $cacheDir;
$this -> cachePath = $cacheDir.$filename;
$this -> timeLimit = is_int($timeLimit) ? $timeLimit : time();
//We check if the directories-tree exists, and create it if it doesn't
$string = '';
$cacheDir = explode('/', $cacheDir);
foreach ($cacheDir AS $dir)
{
if (is_dir($string.$dir) OR @mkdir($string.$dir)) $string .= $dir.'/';
else die ($this -> errors[1]);
}
//We set up the compression level
if ($compression === TRUE) $this -> compressData = TRUE;
elseif (is_int($compression) AND $compression >= 1 AND $compression <= 9)
{
$this -> compressData = TRUE;
$this -> gzLevel = $compression;
}
else $this -> compressData = FALSE;
//We check if the cache file exists, and start a buffer if it doesn't
if (is_readable($this -> cachePath) AND filemtime($this -> cachePath) > (time() - $this -> timeLimit))
{
$this -> cacheExists = TRUE;
if ($this -> compressData)
{
$this -> cacheContents = gzuncompress(file_get_contents($this -> cachePath));
}
else
{
$this -> cacheContents = file_get_contents($this -> cachePath);
}
}
else
{
ob_start();
}
}
//Static methods
public static function clear ($filename, $dir = NULL) //This static method will try to destroy the cache file if it exists
{
$dir = $dir ? $dir : self::$cacheDir;
if (file_exists($dir.$filename)) unlink($dir.$filename);
}
//Public methods
public function lastModified () //This method returns the last-modified timestamp of the cache file
{
if ($this -> cacheExists) return filemtime($this -> cachePath);
else return time();
}
public function show ($print = TRUE) //This method prints (or returns) the cache contents if it exists, or return false
{
if ($this -> cacheExists)
{
if ($print == TRUE)
{
print $this -> cacheContents;
return TRUE;
}
else return $this -> cacheContents;
}
else
{
return FALSE;
}
}
public function close () //This method write the cache file and print the contents
{
$contents = ob_get_clean();
if ($this -> compressData)
{
$cacheContents = gzcompress($contents, $this -> gzLevel);
}
else
{
$cacheContents = $contents;
}
if ($file = @fopen($this -> cachePath, 'w'))
{
fwrite($file, $cacheContents);
fclose($file);
}
else die ($this -> errors[0]);
print $contents;
}
}
class LambdaHTTPCache
{
private $lastModified; //The last-modified time of the document
private $proxy = 'Public'; //The proxy option (public or private)
private $userAgent = FALSE;
//The errors which may be displayed
private $errors = array (
'The $time parameter must be an integer');
//Public methods
public function __construct () { }
public function checkTime ($time) //This method checks if this time is bigger than the last-modified time
{
if (!is_int($time)) die ($this -> errors[0]);
elseif ($time > $this -> lastModified) $this -> lastModified = $time;
}
public function setProxy ($private, $userAgent) //This method adds some parameters to use client proxies
{
if ($private == TRUE) $this -> proxy = 'Private';
if ($userAgent == TRUE) $this -> userAgent = TRUE;
}
public function sendHeaders () //This method sends the HTTP headers
{
$serverDate = gmdate('D, d M Y H:i:s', time());
$lastModifiedDate = gmdate('D, d M Y H:i:s', $this -> lastModified);
header('Date: '.$serverDate.' GMT');
header('Last-Modified: '.$lastModifiedDate.' GMT');
if ($this -> userAgent == TRUE) header ('Vary: User-Agent');
header('Cache-Control: '.$this -> proxy.', must-revalidate');
header('Pragma: '.strtolower($this -> proxy));
$requestDate = substr(@$_SERVER['HTTP_IF_MODIFIED_SINCE'],0,29);
if ($requestDate != '' AND strtotime($requestDate) == $this -> lastModified)
{
header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified', TRUE, 304);
exit;
}
}
}