Sto scrivendo una classe per gestire una cache delle pagine di un sito con un traffico elevato. L'idea è che se una pagina sia già stata "elaborata" il server piuttosto che ri-elabborarla restituisca la copia di cache. Fin qui ci siamo.
Tuttavia la cosa prevede delle eccezioni. Ad esempio se nella pagina ho un form e l'utente ne ha appena fatto il subimit, non devo restituire versioni della pagina in cache, ed anche questo è stato risolto semplicemente controllando se $_POST sia valorizzata.
Però ora mi rimane un ultimo problema abbastanza ostico e cioè, non cachare quelle parti della pagina dove per forza di cose i contenuti saranno sempre diversi, adesempio punti in cui stampo il nome dell'utente o altri dati che ad ogni richiesta saranno estremamente variabili.
Segue la classe che come vedete è abbastanza semplice e una pagina d'esempio. L'obiettivo è che il numero random, indipendentemente dalla cache, rimanga random, quindi servirebbe un qualsiasi sistema che preveda la possibilità di cachere solo parti della pagina. Consigli?
PageCache.class.php
Pagina test.php
Tuttavia la cosa prevede delle eccezioni. Ad esempio se nella pagina ho un form e l'utente ne ha appena fatto il subimit, non devo restituire versioni della pagina in cache, ed anche questo è stato risolto semplicemente controllando se $_POST sia valorizzata.
Però ora mi rimane un ultimo problema abbastanza ostico e cioè, non cachare quelle parti della pagina dove per forza di cose i contenuti saranno sempre diversi, adesempio punti in cui stampo il nome dell'utente o altri dati che ad ogni richiesta saranno estremamente variabili.
Segue la classe che come vedete è abbastanza semplice e una pagina d'esempio. L'obiettivo è che il numero random, indipendentemente dalla cache, rimanga random, quindi servirebbe un qualsiasi sistema che preveda la possibilità di cachere solo parti della pagina. Consigli?
PageCache.class.php
PHP:
class PageCache
{
const CACHE_BASE_PATH = 'C:\xampp\htdocs\www.test.it\tmp\\';
const CACHE_TIME = 3600;
private static $istance;
private $HTMLBuffer;
private function __construct()
{
ob_start();
}
public function __destruct()
{
}
function __clone()
{
return false;
}
function __wakeup()
{
return false;
}
public static function getInstance()
{
if( is_null( self::$istance ) )
{
self::$istance = new self;
}
return self::$istance;
}
public function cacheDisplay()
{
if( $this->isCachable() )
{
$filename = $this->cacheFile();
$content = $this->get_cache_content();
if( $content )
{
$this->HTMLBuffer = $content;
$this->printHTML();
}
}
}
public function cachePage()
{
if( $this->isCachable() )
{
$filename = $this->cacheFile();
$handle = fopen($filename, 'w+');
if( $handle !== false )
{
$content = $this->getBuffer();
fwrite($handle, $content);
fclose($handle);
$this->HTMLBuffer = $content;
$this->printHTML();
}
}
}
public function cacheRemove()
{
$filename = $this->cacheFile();
if( file_exists($filename) )
return unlink($filename);
return false;
}
public function cacheClean()
{
$DelSuccess = 0;
$DelFail = 0;
$files = glob(self::CACHE_BASE_PATH . '*');
foreach( $files as $file )
{
if( is_file($file) )
{
if( unlink($file) )
$DelSuccess++;
else
$DelFail++;
}
else
{
$DelFail++;
}
}
return ( ($DelSuccess > 0) && ($DelFail == 0) );
}
private function cacheExist($filename = NULL)
{
if( is_null($filename) )
return false;
if( !file_exists($filename) )
return false;
if( filemtime($filename) <= (time() - self::CACHE_TIME) )
return false;
return true;
}
private function isCachable()
{
return ( count($_POST) <= 0 );
}
private function printHTML()
{
if( is_null($this->HTMLBuffer) )
{
$this->HTMLBuffer = $this->getBuffer();
}
die($this->HTMLBuffer);
}
private function sanitizeOutput($buffer) {
$search = array('/\>[^\S ]+/s','/[^\S ]+\</s','/(\s)+/s');
$replace = array('>','<','\\1');
$buffer = preg_replace($search, $replace, $buffer);
return $buffer;
}
private function cacheFile()
{
return self::CACHE_BASE_PATH . md5( $_SERVER['REQUEST_URI'] );
}
private function get_cache_content()
{
$filename = $this->cacheFile();
if( $this->cacheExist($filename) )
{
return file_get_contents($filename);
}
return null;
}
private function getBuffer()
{
return $this->sanitizeOutput(ob_get_clean());
}
}
Pagina test.php
PHP:
<?php
require_once 'PageCache.class.php';
$CacheObj = PageCache::getInstance();
// $CacheObj->cacheRemove();
// $CacheObj->cacheClean();
$CacheObj->cacheDisplay();
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p>Hello world! <?</p>
<form action="?" method="post">
POST <input type="text" name="test1" value="<?php echo ( isset($_POST['test1']) ) ? $_POST['test1'] : ''; ?>">
<input type="submit">
</form>
<form action="?" method="get">
GET <input type="text" name="test2" value="<?php echo ( isset($_GET['test2']) ) ? $_GET['test2'] : ''; ?>">
<input type="submit">
</form>
<p>Data elaborazione pagina: <?php echo date('d/m/Y H:i:s'); ?></p>
<p>Random: <?php echo rand(); ?></p>
</body>
</html>
<?php $CacheObj->cachePage(); ?>