[risolto] cache dell'html di output

skillsfactory

Utente Attivo
23 Nov 2012
50
0
0
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

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(); ?>
 
vabbè come non detto... ho risolto da solo... posto il codice se può servire a qualcuno

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 __get($property) 
	{
		if ( property_exists($this, $property) ) 
		{
			return $this->$property;
		}
		
		return null;
	}

	
	
	public function __set($property, $value) 
	{
      	$this->$property = $value;
	}
	
	
	public function cacheDisplay() 
	{
		if( $this->isCachable() )
		{
			$filename = $this->cacheFile();
	
			$content = $this->get_cache_content();	
			
			if( $content )
			{
				$this->HTMLBuffer = $content;
				
				$this->printHTML();
			}
		}
	}

	
	private function replaceVars($buffer = '')
	{
		$buffer = preg_replace_callback('/\{\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/i',
		function ($matches) {
			$replace = $this->__get($matches[1]);
			return str_ireplace($matches[0], $replace, $matches[0]);
		},
		$buffer
		);
		
		
		return $buffer;
	}
	
	
	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();
			} 
		}
                else
		{
			$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();
		}
	
		$this->HTMLBuffer = $this->replaceVars($this->HTMLBuffer);
		
		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());
	}
}




PHP:
<?php 
 require_once 'PageCache.class.php';
 
 
 $CacheObj = PageCache::getInstance();
 
 //$CacheObj->cacheRemove();
 //$CacheObj->cacheClean();
 
 $CacheObj->__set('RANDOM',   rand() );
 $CacheObj->__set('USERNAME', 'User_'.rand() );

 
 $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 {$USERNAME}!</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: {$RANDOM}</p> 
        <p>User:   {$USERNAME}</p> 
        <p>NotSet:   {$NOTSET}</p> 

    </body>
</html>
<?php $CacheObj->cachePage(); ?>
 
Ultima modifica:

Discussioni simili