PHP Classes

File: cache.class.php

Recommend this page to a friend!
  Classes of Patxi Echarte   phpSuperCache   cache.class.php   Download  
File: cache.class.php
Role: ???
Content type: text/plain
Description: Class file
Class: phpSuperCache
Author: By
Last change:
Date: 22 years ago
Size: 13,162 bytes
 

Contents

Class file image Download
<?php /*-------------------------------------------------------------------------------- Application: phpSuperCache ========================== Archivo: cache.class.php Autor: Francisco Echarte [patxi@eslomas.com] Fecha: 2001-08-23 Version: 0.2 Clases: cacheManager => guarda en cache y recupera, páginas enteras o bloques LICENCIA ======== copyright (c) 2001 Francisco Echarte [patxi@eslomas.com] This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. This library 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 Lesser General Public License for more details at http://www.gnu.org/copyleft/lgpl.html 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Modificaciones: .- Se añade el manejo de CACHE_QUERYS para decidir mediante expresiones regulares que URIS se cachean Observaciones: .- Desarrollado tomando como base toncarta, de heyes-computing.net .- Utiliza únicamente el filesystem, por se lo más rápido. No se usa una BD, con el fin de evitar el cuello de botella que implica la solicitud continua de conexiones. .- Las páginas son almacenadas en texto plano y en comprimido (gzip), con el fin de ofrecer el contenido de la cache comprimido, si el navegador del usuario lo soporta. --------------------------------------------------------------------------------*/ include_once(dirname(__FILE__).'/cache.config.php'); include_once(dirname(__FILE__).'/cache.timings.php'); class cacheManager{ var $request_uri; //Para guardar solicitdud del usuario var $query_string; //Para guardar la query solicitada var $php_self; //Para guardar página solicitada var $gzip_supported; //Para indicar si en la petición, el navegador del //usuario soporta información en formato gzip var $genereting_output; //Para indicar cuando se está generando output para //guardar en cache /*--------------------------------------------------------------------------- Entrada: Salida : Efecto : Construtcr de la clase, inicializa las variables. Ejecuta la autolimpieza con cierta probabilidad, si la opción está activada ---------------------------------------------------------------------------*/ function cacheManager(){ global $CACHE_CONFIG; $this->gzip_supported = 0; $this->genereting_output = 0; $this->request_uri = $GLOBALS[REQUEST_URI]; $this->query_string = $GLOBALS[QUERY_STRING]; $this->php_self = basename($GLOBALS[PHP_SELF]); $CACHE_CONFIG['run_cleanup'] == 1? $this->cacheCleanup() : NULL; // Miro si el navegador del usuario permite envío de información comprimida if(strpos(" ".$GLOBALS[HTTP_ACCEPT_ENCODING],'gzip') !== 0) $this->gzip_supported = 1; else $this->gzip_supported = 0; } /*--------------------------------------------------------------------------- Entrada: Salida : Si la página existe en cache, devuelve el contenido y finaliza el script. Efecto : Si la página solicitada por el usuario está entre las que hay que cachear, comprueba si hay una copia disponible y la envía, finalizándose la ejecución. Si no hay una copia disponible, se inicializa el output buffer, para poder luego capturar la salida generada por el script. ---------------------------------------------------------------------------*/ function startCachingPage(){ global $CACHE_TIMINGS, $CACHE_CONFIG, $CACHE_QUERYS; if($CACHE_TIMINGS[$this->php_self] > 0 && ($this->query_string == '' || ereg($CACHE_QUERYS[$this->php_self],$this->query_string) ) ){ // // Está la página cacheada ? // list($cached_page,$gzip) = $this->checkCache($this->request_uri,$CACHE_TIMINGS[$this->php_self]); if($cached_page != ''){ // Compressed? if($CACHE_CONFIG['return_compressed'] == 1 AND $gzip== 1){ header ("Content-Encoding: gzip"); } echo $cached_page; $this->logVisit($this->request_uri, 'HIT', $gzip); exit; } else{ ob_start(); $this->genereting_output = 1; $this->logVisit($this->request_uri, 'MISS', $gzip); } } else{ $this->logVisit($this->request_uri, 'EXCL', $gzip); } } /*--------------------------------------------------------------------------- Entrada: Salida : Efecto : Si la página solicitada por el usuario está entre las que hay que cachear, comprueba si hay una copia disponible y la envía, finalizándose la ejecución. Si no hay una copia disponible, se inicializa el output buffer, para poder luego capturar la salida generada por el script. ---------------------------------------------------------------------------*/ function endCachingPage(){ global $CACHE_CONFIG; if($this->genereting_output == 1){ $output = ob_get_contents(); ob_end_clean(); $this->insertIntoCache($output, $this->request_uri); } } /*---------------------------------------------------------------------- Entrada: $request => indica la página (uri) o bloque que se quiere comprobar $refresh => indica el tiempo de permanencia en cache de la solicitud $compressed => indica si se prefiere salida comprimida. Si la solicitud es para un bloque debe ser false!!! Salida : Si se consigue obtener (HIT) la solicitud de cache, se devuelve un array con el contenido y true o false indicando si está comprimido o no. Si no se puede realizar la solicitud (MISS) se devuelve un array con FALSE y false como comprimido Efecto : a partir de la solicitud y compressed, con md5 se crea el nombre de que tendría en cache. Si el archivo existe se compara su fecha con el tiempo de permanencia. En el caso de que se solicite comprimido y este no exista, se intenta obtener la versión sin comprimir. ----------------------------------------------------------------------*/ function checkCache($request,$refresh,$compressed = '-1'){ global $CACHE_CONFIG; $filename = $CACHE_CONFIG['data_dir'].md5($request); if($compressed == '-1') $compressed = $this->gzip_supported; if($CACHE_CONFIG['return_compressed'] == 1 && $compressed == 1) $filename .= ".gz"; if(file_exists($filename)){ if(filemtime($filename) > time()-$refresh){ $data = fread($fp = fopen($filename, 'r'), filesize($filename)); fclose($fp); return array($data,$compressed); } else return array(0,1); } else if($compressed == 1) $this->checkCache($request,$refresh,0); else return array(0,0); } /*---------------------------------------------------------------------- Entrada: $content => el contenido $request => la solicitud Salida : se imprime el contenido que se ha metido en cache Efecto : se crea un archivo en el filesystem en base al nombre de la solicitud codificándolo con md5. Además si está habilitada la opción de guardar comprimido, se guarda el mismo archivo con extensión gz. Esto se puede realizar exista o no la función gzcompress, utilizando una llamada al shell para gzip. ----------------------------------------------------------------------*/ function insertIntoCache($content, $request){ global $CACHE_CONFIG; $content .= "\n<!-- CACHED AT: " . date('Y/m/d : H:m:s') . " BY phpSuperCache -->\n"; $nombre = $CACHE_CONFIG['data_dir'].md5($request); if($fp = fopen($nombre, 'w')){ flock($fp, LOCK_EX); fwrite($fp,$content); flock($fp, LOCK_UN); fclose($fp); if($CACHE_CONFIG['compress_output'] == 1){ if(function_exists('gzcompress')){ $gzcontent = "\x1f\x8b\x08\x00\x00\x00\x00\x00"; $Size = strlen($content); $Crc = crc32($content); $aux = gzcompress($content,$level); $gzcontent .= substr($aux, 0, strlen($aux) - 4); $gzcontent .= pack('V',$Crc); $gzcontent .= pack('V',$Size); $fp = fopen("$nombre.gz",'w'); flock($fp, LOCK_EX); fwrite($fp,$gzcontent); flock($fp, LOCK_UN); fclose($fp); } else{ exec("cp $nombre $nombre.bak;gzip $nombre.bak;mv $nombre.bak.gz $nombre.gz"); } } } echo $content; } /*---------------------------------------------------------------------- Entrada: $request => indica la solicitud realizada $type => el resultado de la solicitud (HIT, MISS, EXCL) $compressed => si se ha devuelto el resultado comprimido o no Salida : nada Efecto : añade una línea al log, si la opción esta activa. ----------------------------------------------------------------------*/ function logVisit($request, $type, $compressed){ global $CACHE_CONFIG; if(!$CACHE_CONFIG['save_stats']) return; if($compressed == 1) $compressed = 'true'; else $compressed = 'false'; $logfile = $CACHE_CONFIG['data_dir'].'stats.log'; $fp = fopen($logfile, 'a'); flock($fp, LOCK_EX); fseek($fp, filesize($logfile)); $salida = sprintf("%-10s %-74s %-4s %-5s\r\n",time(),$request,$type,$compressed); //fwrite($fp, time().' '.urlencode($request).' '.$type.' '.$compressed."\r\n"); fwrite($fp, $salida); flock($fp, LOCK_UN); fclose($fp); } /*---------------------------------------------------------------------- Entrada: nada Salida : nada Efecto : elimina los archivos del filesystem correspondientes a cachings viejos ----------------------------------------------------------------------*/ function cacheCleanup(){ global $CACHE_CONFIG; srand((double)microtime()*1000000); $num = rand(1,100); if($num <= $CACHE_CONFIG['cleanup_freq']){ $dh = opendir($CACHE_CONFIG['data_dir']); while($filename = readdir($dh)){ if($filename === '.' OR $filename === '..') continue; if(filemtime($CACHE_CONFIG['data_dir'].$filename) < time() - $CACHE_CONFIG['max_age']) unlink($CACHE_CONFIG['data_dir'].$filename); } } } /*---------------------------------------------------------------------- Entrada: un string correspondiente a un nombre de bloque Salida : false si el bloque no está en cache y true si lo está. Además en caso de que esté en cache, se muestra. ----------------------------------------------------------------------*/ function getCachedBlock($block){ global $CACHE_TIMINGS; list($cached_contents,$gzip) = $this->checkCache($block,$CACHE_TIMINGS[$block],0); if($cached_contents){ echo $cached_contents; $this->logVisit($block, 'HIT', $gzip); return true; } else return false; } /*---------------------------------------------------------------------- Entrada: $block => nombre de bloque $contents => el contenido del bloque Salida : imprime el contenido Efecto : guarda el contenido del bloque en cache y lo imprime. Si el bloque no tiene asignado un tiempo de permanencia, se muestra un error. ----------------------------------------------------------------------*/ function setCachedBlock($block,$contents){ global $CACHE_TIMINGS; if(!isset($CACHE_TIMINGS[$block])){ $this->logVisit($block, 'EXCL', 0); return; } else{ $this->insertIntoCache($contents,$block); $this->logVisit($block, 'MISS', 0); } } } ?>