Il caching delle pagine Web

20 marzo 2006

Un’implementazione alternativa

Dopo aver presentato un’implementazione introduttiva del caching di una pagina, vi mostrerò come è possibile, con poco e semplice codice, implementare un sistema leggermente più avanzato, che permetta di rispondere a tutti i punti elencati nel paragrafo precedente.

Lo script seguente fornirà una semplice libreria composta da due classi che si occuperanno di gestire il caching delle vostre pagine ed alcune funzioni di utilità. La prima classe, CacheContent, servirà per la gestione dell’output di una sezione di codice PHP: si occuperà di creare la cache, visualizzarla, settare eventuali modificatori che tengano traccia dell’input ricevuto dalla pagina e settare il timeout della cache. La seconda classe, HtmlCache, si occuperà di gestire i dati salvati in cache, generando istanze di CacheContent quando richiesto.

<?php

define(“INVALID_DIR”, 501);

define(“FLAGS_NONE”, 0x0);
define(“USE_GET”, 2 << 0);
define(“USE_POST”, 2 << 1);
define(“USE_CUSTOM”, 2 << 2);

define(“CACHE_CREATED”, 2);
define(“CACHE_READ”, 1);

function CacheError($code){

   switch($code){
      case INVALID_DIR:
         $error = “Ivalid cache directory specified.”;
      break;
      default:
         $error = “Unknown Error”;
      break;
   }
   
   die(“Cache error: “.$error);
   exit();
}

class CacheContent {

   var $working_directory = “”;
   var $name_modifiers = array();
   var $timeout = 0;
   var $file_extension = “”;
   
   var $fp = null;
   var $type = -1;
   
   function CacheContent($dir, $ext, $n){
      $this->working_directory = $dir.”/”.basename($_SERVER[‘PHP_SELF’]).”/”;
      if(!file_exists($this->working_directory))
         mkdir($this->working_directory);
      array_push($this->name_modifiers, $n);
      $this->file_extension = $ext;
   }
   
   function SetNameModifier($mod){
      $new = array();
      foreach($mod as $key=>$val){
         if(is_array($val)){
            $this->SetNameModifier(array_merge(array($key), $val));
         }else array_push($new, $key.$val);
      }
      array_merge($this->name_modifiers, $new);
   }
   
   function SetTimeout($timeout){
      $this->timeout = $timeout;
   }
   
   function Create(){
      
      $expired = false;
      
      $file_id = md5(implode(“”, $this->name_modifiers));
      $file_name = $file_id.”.”.$this->timeout.$this->file_extension;
      if(file_exists($this->working_directory.$file_name)){
         if(time() > filemtime($this->working_directory.$file_name)+$this->timeout){
            $expired = true;
         }else echo file_get_contents($this->working_directory.$file_name);
      }else $expired = true;

      if($expired){
         $this->fp = fopen($this->working_directory.$file_name, “w”);
         ob_start();
         $this->type = CACHE_CREATED;
         return;
      }
      $this->type = CACHE_READ;
   }
   
   function GetType(){
      return $this->type;
   }
   
   function Stop(){
      if(!is_null($this->fp)){
         fwrite($this->fp, ob_get_contents());
         fclose($this->fp);
         
         ob_end_flush();
      }
   }
   
}

class HtmlCache {
   
   var $cached_dir = “”;
   var $cached_files_ext = “”;
   var $cached_global_timeout = “”;
   
   var $cached_counter = 0;
   
   function HtmlCache($dir, $ext, $timeout){
      
      $dir = $_SERVER[‘DOCUMENT_ROOT’].dirname($_SERVER[‘PHP_SELF’]).”/”.$dir;

      if(!file_exists($dir)){
         mkdir($dir.”/”.basename($_SERVER[‘PHP_SELF’]).”/”, 0700);
      }
      $this->cached_dir = $dir;
      
      $this->cached_files_ext = $ext;
      $this->cached_global_timeout = intval($timeout, 10);
   }
   
   function Create($flags = 0x0, $timeout = null, $custom_data = null){
      
      $cache = new CacheContent($this->cached_dir, $this->cached_files_ext, $this->cached_counter);
      $this->cached_counter++;
      if($flags & USE_GET){
         global $_GET;         
         $cache->SetNameModifier($_GET);
      }
      if($flags & USE_POST){
         global $_POST;
         $cache->SetNameModifier($_POST);
      }
      if($flags & USE_CUSTOM){
         $custom_data = (is_array($custom_data) && $custom_data != null) ? $custom_data : array($custom_data);
         $cache->SetNameModifier($custom_data);
      }
      
      $timeout = is_numeric($timeout) ? $timeout : $this->cached_global_timeout;
      $cache->SetTimeout($timeout);
      
      $cache->Create();
      return $cache;
   }
}

?>

Descriviamo brevemente il codice presentato qui sopra:
  • I primi define si occupano di definire delle costanti che verranno utilizzate dalla libreria; abbiamo definiti delle tipologie di errore, dei flag utilizzati per comunicare alla libreria che dati utilizzare per la generazioni di ID univoci in base ad input esterno, e due stati utilizzati per comunicare allo script se la cache è stata creata oppure letta.
  • La funzione CacheError si occupa di controllare che errore è stato generato e di eseguire un report differente in base all’errore; per ora gestisce solamente il caso in cui sia stata specificata una directory errata per contenere le cache.
  • Il costruttore della classe CacheContent accetta tre parametri rappresentati rispettivamente la directory in cui contenere la cache, l’estensione dei file salvati in cache, ed un codice utilizzato per indicare univocamente la cache. Questi dati vengono salvati e viene creata la directory di lavoro (in cui saranno salvate le cache della pagina corrente).
  • Il metodo SetNameModifier accetta un unico parametro rappresentato da un array contenete i dati utilizzati per indicare univocamente una porzione di cache. A questo metodo, per esempio, potrà essere passato l’array $_POST per salvare una cache differente in base ai dati inviati tramite form.
  • Il metodo SetTimeout setta il timeout della cache.
  • Il metodo Create si occupa di generare il nome del file utilizzato per la cache basandosi sui modificatori eventualmente assegnati, controllare che la cache non sia scaduta ed in caso affermativo visualizzarla. In caso negativo svuota la vecchia cache ed inizializza l’output buffering di PHP al fine di poter salvare l’ouput generato successivamente. Il metodo si occupa anche di settare il tipo di CacheContent.
  • Il metodo Stop, infine, si occupa di salvare l’output generato da PHP solamente nel caso in cui la cache debba essere aggiornata.
  • Il costruttore della classe HtmlCache accetta tre parametri: i primi due rappresentano la directory in cui salvare la cache e l’estensione dei file di cache, mentre il terzo rappresenta il secondi di vita della cache utilizzati nel caso in cui il timeout non sia specificato nel metodo create.
  • Il metodo Create della classe HtmlCache accetta tre parametri: il primo rappresenta una serie di flag utilizzati per informare la libreria di quali dati utilizzare per la generazione del modificatore, il secondo rappresenta il timeout della singola sezione di cache e l’ultimo rappresenta un array di dati custom utilizzati per la generazione del modificatore nel caso in cui il primo parametro contenga il flag USE_CUSTOM. Il metodo crea un CacheContent e lo restituisce al chiamante.

Se vuoi aggiornamenti su Il caching delle pagine Web inserisci la tua e-mail nel box qui sotto:
 
X
Se vuoi aggiornamenti su Il caching delle pagine Web

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy