Blame | Last modification | View Log | Download | RSS feed
<?php
/* fastcache.inc -- gestione veloce di cache file con validità
* temporale impostabile dall'utente.
* L'accesso al file da parte di processi
* concorrenti viene serializzato.
*
* Il file fastcache_test.php contiene un esempio di uso.
*
* Versione 1.1, ultima modifica 8 marzo 2004 [27781]
*/
/* La funzione fcache_read legge il contenuto di un cache file
* e lo deserializza nella variabile PHP passata come argomento.
*
* Parametri di input:
*
* $fname = nome del file di cache da leggere. Si consiglia di
* fornire il path completo.
* $data = variabile passata per riferimento, che viene impostata
* con il risultato della deserializzazione dei dati letti
* nel file di cache.
*
* Codici di ritorno:
*
* 0 = Tutto OK.
* 1 = File inesistente.
* 2 = Impossibile creare lock file.
* 3 = Impossibile acquisire READ lock.
* 4 = Impossibile aprire il file in lettura.
* 5 = Cache scaduta.
* 6 = Impossibile deserializzare i dati.
*/
function fcache_read($fname, &$data)
{
clearstatcache();
if(false == file_exists($fname))
return(1); // File inesistente.
$om = file_exists($fname.'.lock') ? 'rb' : 'ab';
$fd = @fopen($fname.'.lock', $om);
if(false == $fd)
return(2); // Impossibile creare lock file.
if(!(@flock($fd, LOCK_SH)))
{
@fclose($fd);
return(3); // Impossibile acquisire READ lock.
}
$fh = @fopen($fname, 'rb');
if(false == $fh)
{
@flock($fd, LOCK_UN);
@fclose($fd);
return(4); // Impossibile aprire il file in lettura.
}
$ts = hexdec(rtrim(@fgets($fh, 32)));
if(time() > $ts)
{
@fclose($fh);
@flock($fd, LOCK_UN);
@fclose($fd);
return(5); // Cache scaduta.
}
$s = '';
while(!feof($fh))
$s .= fread($fh, 8192);
@fclose($fh);
@flock($fd, LOCK_UN);
@fclose($fd);
$data = unserialize($s);
if(false == $data)
return(6); // Impossibile deserializzare i dati.
return(0); // Tutto OK.
}
/* La funzione fcache_write inizializza il contenuto di un cache file
* con i dati passati ed imposta il periodo di validità di questi ultimi.
*
* Parametri di input:
*
* $fname = nome del file di cache da scrivere. Si consiglia di
* fornire il path completo.
* $data = variabile che contiene i dati da impostare. Ciascun cache file
* contiene solo una variabile PHP, ma questa può essere anche un
* array associativo multidimensionale grande a piacere. Su Linux
* si consiglia di scrivere i file nel filesystem /dev/shm che è
* contenuto in memoria e di dimensioni massime pari a metà della
* memoria fisica della macchina.
* Ovviamente questo significa che i file in /dev/shm devono essere
* di piccole dimensioni e sacrificabili in caso di shutdown o crash
* del server: qualora non fosse rispettato uno dei vincoli esposti
* il cache file va creato su disco, magari in una directory tmp dove
* i file non più usati vengono automaticamente cancellati.
* $timeout = numero di secondi di validità del cache file. Il parametro può
* essere omesso nella chiamata, ed in tal caso viene impostato
* a 60 secondi.
*
* Codici di ritorno:
*
* 0 = Tutto OK.
* 1 = Non ci sono dati da scrivere!
* 2 = Impossibile creare lock file.
* 3 = Impossibile acquisire WRITE lock.
* 4 = Impossibile aprire il file in scrittura.
* 5 = Fallita scrittura cache file.
* 6 = Il timeout non è valido.
*/
function fcache_write($fname, $data, $timeout = 60)
{
if(empty($data))
return(1); // Non devo scrivere niente!
if(!is_numeric($timeout) || $timeout <= 0)
return(6); // Il timeout non è valido.
clearstatcache();
$om = file_exists($fname.'.lock') ? 'rb' : 'ab';
$fd = @fopen($fname.'.lock', $om);
if(false == $fd)
return(2); // Impossibile creare lock file.
if(!(@flock($fd, LOCK_EX)))
{
@fclose($fd);
return(3); // Impossibile acquisire WRITE lock.
}
$fh = @fopen($fname, 'wb');
if(false == $fh)
{
@flock($fd, LOCK_UN);
@fclose($fd);
return(4); // Impossibile aprire il file in scrittura.
}
$buffer = dechex(time() + (int)$timeout)."\n".serialize($data);
$rc = @fwrite($fh, $buffer, strlen($buffer));
@fclose($fh);
if(0 == $rc)
{
@unlink($fname);
@flock($fd, LOCK_UN);
@fclose($fd);
return(5); // Fallita scrittura cache file.
}
@flock($fd, LOCK_UN);
@fclose($fd);
return(0); // Tutto OK.
}
/* La funzione fcache_delete cancella un cache file incondizionatamente.
*
* Parametri di input:
*
* $fname = nome del file di cache da cancellare. Si consiglia di
* fornire il path completo.
*
* Codici di ritorno:
*
* 0 = Tutto OK.
* 1 = File inesistente.
* 2 = Impossibile creare lock file.
* 3 = Impossibile acquisire WRITE lock.
*/
function fcache_delete($fname)
{
clearstatcache();
if(false == file_exists($fname))
return(1); // File inesistente.
$om = file_exists($fname.'.lock') ? 'rb' : 'ab';
$fd = @fopen($fname.'.lock', $om);
if(false == $fd)
return(2); // Impossibile creare lock file.
if(!(@flock($fd, LOCK_EX)))
{
@fclose($fd);
return(3); // Impossibile acquisire WRITE lock.
}
@unlink($fname);
@unlink($fname.'.lock');
@flock($fd, LOCK_UN);
@fclose($fd);
return(0); // Tutto OK.
}
?>