del($nome);
if (isset($this->dati[$this->prefisso.$this->procedura][$nome]))
$valore=@unserialize($this->dati[$this->prefisso.$this->procedura][$nome]['Dati']);
if ($valore===false) return $this->dati[$this->prefisso.$this->procedura][$nome]['Dati'];
else return $valore;
}
/** Restituisce un array associativo con più valori della sessione
* @param array $nomi array non associativo con l'elenco dei nomi da usare nell'estrazione, se omesso si estrarranno tutte i valori della sessione
* @return qualunque
*/
function gets($nomi=array()) {
$v=array();
if(self::$nomi) foreach (self::$nomi as $nome) if (!$nomi || in_array($nome,self::$nomi))
{$v[$nome]=$this->get($nome);
if ($v[$nome]===null) unset($v[$nome]);
}
return $v;
}
/** Elimina $nome dalla sessione
* @param string $nome
*/
function del($nome) {
unset(self::$nomi[$nome]);
unset($this->dati[$this->prefisso.$this->procedura][$nome]);
}
/** Elimina tutte le voci in $nomi dalla sessione
* @param array $nomi non associativo con l'elenco dei nomi da usare nell'estrazione, se omesso SI DISTRUGGE TUTTO IL CONTENUTO DELL'INTERA SESSIONE
*/
function dels($nomi=array()) {
if(self::$nomi)
foreach (self::$nomi as $nome=>$null) if (!$nomi || in_array($nome,self::$nomi)) $this->del($nome);
}
/**
* Crea una variabile GLOBALE di nome $nome estraendola (se esiste) dalla sessione
* Es. Se in uno script scriviamo:
*
* include_once('../MyForms/mySessions.php');
* $s=new MySessions('procedura_x'); //istanzio la classe
* $s->set('CF',$_GET['CODICE_FISCALE']); //senza terzo parametro ha effetto solo quando $_GET è valorizzato
* ...
*
*
* Ed in un altro script scriviamo:
*
* include_once('../MyForms/mySessions.php');
* $s=new MySessions('procedura_x');
* $s->globalize('CF');
* //da questo momento esiste una variabile $CF con il valore precedentemente memorizzato nella sessione
* ...
*
*
* @param string $nome
* @return void
*/
function globalize($nome) {
global $$nome;
$$nome=$this->get($nome);
}
/**
* Forza il salvataggio dei dati della sessione
* @link http://it2.php.net/manual/it/function.session-write-close.php
*
*/
function flush() {
session_write_close();
}
/**
* Crea tante variabili GLOBALI con i nomi nell'array $nomi estraendone i valori (se esistono) dalla sessione
* Es. Se in uno script scriviamo:
*
* include_once('../MyForms/mySessions.php');
* $s=new MySessions('procedura_x');//istanzio la classe
* $s->set('CF',$_GET['CODICE_FISCALE']); //senza terzo parametro ha effetto solo quando $_GET è valorizzato
* $s->set('ALTRO','PIPPO',true); //forza l'inserimento di ALTRO nella sessione con valore PIPPO
* ...
*
*
* Ed in un altro script scriviamo:
*
* include_once('../MyForms/mySessions.php');
* $s=new MySessions('procedura_x');
* $s->globalizes( array('CF','ALTRO') );
* //da questo momento esistono sia $CF che $ALTRO con i valori precedentemente memorizzati nella sessione
* ...
*
*
* @param array $nomi
* @return void
*/
function globalizes($nomi=array()) {
if (count($nomi))
foreach ($nomi as $nome) $this->globalize($nome);
}
/** Vedi globalize ma per la sessione generale
* @param string $nome
**/
function globalize_general($nome) {
global $$nome;
$$nome=$this->get_general($nome);
}
}
/**
* Analoga alle mySessions nei metodi ma diversa nel funzionamento.
* Tutte le variabili vengono salvate in dei file condivisi da tutti gli script.
* Mentre i dati di una mySessions sono accessibili dagli script eseguiti nell'ambito di una finestra del browser
* i dati di una MyFileSessions sono condivisi tra tutti gli script ini esecuzione e non si perdono quando si chide la finestra (come con le sessioni).
* Utile quando ci sono informazioni che si vogliono condividere per migliorare le prestazioni indipendentemente dalle sessioni attive (es. numero di accessi)
*
*
* LE OPERAZIONI DI SET E GET PERVEDONO SEMPRE SERIALIZE ED UNSERIALIZE DEL VALORE (ATTENZIONE AGLI OGGETTI QUINDI)
* I DATI VENGONO SALVATI AUTOMATICAMENTE AL TERMINE DELLO SCRIPT O ATTRAVERSO IL METODO flush()
*
*
* PROVARE A LANCIARE QUESTO SCRIPT DA DUE SESSIONI DIVERSE E CONFRONTARLO CON IL COMPORTAMENTO DELL'ANALOGO SCRIPT DELLE mySessions.
*
*
* include('myForms/mySessions.php');
*
* $s1=new MyFileSessions('PROCEDURA A'); //istanzio una mySession per la Procedura A
* echo " Valore pippo in PROCEDURA A:".$s1->get('pippo');//visualizzo l'eventuale valore associato alla chiave 'pippo' della PROCEDURA A
* $s1->set('pippo',$s1->get('pippo')+1,'',10); //incremento il precedente valore e lo salvo per 10 secondi
*
* echo " Valore pippo in GENERAL:".$s1->get_general('pippo'); //recupero dalla sessione un valore Generale di 'pippo' (comune a tutte le PROCEDURE e distinto da quello della PROCEDURA A)
* $s1->set_general('pippo',$s1->get_general('pippo')+1,'',10); //incremento il precedente valore e lo salvo per 10 secondi
*
* $s2=new MyFileSessions('PROCEDURA B'); //istanzio una mySession per la Procedura B
* echo " Valore pippo in PROCEDURA B:".$s2->get('pippo'); //visualizzo l'eventuale valore associato alla chiave 'pippo' della PROCEDURA B
* $s2->set('pippo',$s2->get('pippo')+1,'',10); //incremento il precedente valore e lo salvo per 10 secondi
*
* echo " Valore pippo in GENERAL:".$s2->get_general('pippo'); //recupero dalla sessione un valore Generale di 'pippo' (comune a tutte le PROCEDURE e distinto da quello della PROCEDURA A)
* $s2->set_general('pippo',$s2->get_general('pippo')+1,'',10); //incremento il precedente valore e lo salvo per 10 secondi
*
* Rieseguire questo script ad intervalli di meno di 10 secondi per valutare come si incrementano le variabili,
* poi attendere 10 secondi e rilanciarlo per osservare come le variabili si azzerino.
*
* Notare che il valore valore Generale di 'pippo' è comune a tutte le istanze mySessions, ed è inoltre facilmente accessibile da altri script che accedono
* alla $_SESSION direttamente, consiglio quindi di usare i metodi set_general e get_general con estrema cautela e comunque
* dando alle variabili nomi particolari.
*
*
*
* @access public
* @package mySessions
*
*/
class myFileSessions extends MyStorageSessions {
/**#@+ @ignore */
protected $percorso='', $prefisso='MFS_', $stato=null, $modificate=array();
protected static $percorso_default;
protected function my_delete($k) {return mySessions::del($k);}
protected function my_store($k,&$v,$ttl=0) {}
protected function my_get($k) {}
function is_available(){return @is_dir($this->percorso);}
/**#@-*/
/**
* Costruttore di classe
* @access public
* @param string $procedura E' il nome della procedura in uso,
* tutti gli script che usano MyFileSessions con la stessa $procedura vedranno
* le medesime variabili, $procedura non può essere una stringa nulla
*/
function __construct($procedura,$directory='') {
static $dati,$modificate;
if (!$procedura) {return null;}
$this->procedura=$procedura;
if ($directory) {if(!is_dir($directory)) @mkdir($directory,0777,true);
$this->percorso=$directory;
}
if (!is_dir($this->percorso)) {if(!is_dir(self::$percorso_default)) @mkdir(self::$percorso_default,0777,true);
$this->percorso=self::$percorso_default;
}
if (!is_dir($this->percorso)) $this->percorso=ini_get('session.save_path');
if (!is_dir($this->percorso)) $this->percorso=$_SERVER["TEMP"];
if (!is_dir($this->percorso)) $this->percorso=dirname(__FILE__);
$this->percorso.='/MyFileSessions';
if (!is_dir($this->percorso) && !@mkdir($this->percorso,null,1)) return null;
$this->modificate=&$modificate;
$this->dati=&$dati;
if(!is_array(self::$nomi)) self::$nomi=array_flip(@array_keys((array) $this->dati[$this->prefisso.$this->procedura]));
if (!$this->dati[$this->prefisso.$this->procedura]) $this->load_procedura();
}
/**
* Imposta il percorso di default in cui verranno salvati i dati delle istanze myFileSessions
*
* @param string $percorso
*/
static function set_percorso_default($percorso){
self::$percorso_default=$percorso;
}
function set_compress_status($status) {}
function get_status() {
return $this->stato;
}
/** @ignore */
function flock_get_contents($filename){
$return=false;
if($handle = @fopen($filename, 'r'))
{flock($handle, LOCK_SH);
$return=@fread($handle,filesize($filename));
flock($handle, LOCK_UN);
@fclose($handle);
}
return $return;
}
/**
* Ottiene un lock basato su file tra script diversi se true lock ottenuto, false non ottenuto
*
* @param string $nome_lock codice mnemonico lock
* @param int $attesa_max attesa massima in microsecondi (su windows e con PHP<5.3 il lock è sempre bloccante quindi l'attesa non è applicabile) , 0 non ha attesa affatto
* @param int $timeout_naturale inapplicato, il lock si rilascia con mySession::release_lock() o quando lo script termina
* @return boolean
*/
function get_lock($nome_lock,$attesa_max=0,$timeout_naturale=0) {
$fine=microtime(1)+$attesa_max/1000000;
$pref=str_replace(array('*','?',':','>','<','|'),'_',$this->prefisso);
$this->locks[$nome_lock]=array('file'=>"{$this->get_nome_file_procedura()}.{$nome_lock}.lck");
print_r($this->locks[$nome_lock]);
do {
if(!is_resource($this->locks[$nome_lock]['res'])) $this->locks[$nome_lock]['res']=@fopen($this->locks[$nome_lock]['file'],'c');
if(is_resource($this->locks[$nome_lock]['res'])) $this->locks[$nome_lock]['lock']=@flock($this->locks[$nome_lock]['res'], LOCK_NB|LOCK_EX);
} while (!$this->locks[$nome_lock]['lock'] && microtime(1)<=$fine);
if(!$this->locks[$nome_lock]['lock']) unset($this->locks[$nome_lock]);
return $this->locks[$nome_lock]['lock'];
}
/** @ignore */
function load_general($handle='') {
if (!$handle) $dati=@$this->flock_get_contents($this->get_nome_file_generale());
else $dati=@fread($fp,@filesize($this->get_nome_file_generale()));
if ($dati===false) return false;
$this->dati[$this->prefisso]=@unserialize($dati);
if (!$this->dati[$this->prefisso]) $this->dati[$this->prefisso]=array();
if (time()-@filemtime($this->get_nome_file_generale())>3600*24) $this->check_scaduti_generale();
return true;
}
function get($nome) {
return mySessions::get($nome);
}
/** @ignore */
function load_procedura($handle='') {
if (!$handle) $dati=@$this->flock_get_contents($this->get_nome_file_procedura());
else $dati=@fread($fp,@filesize($this->get_nome_file_procedura()));
if ($dati===false) return false;
$this->dati[$this->prefisso.$this->procedura]=@unserialize($dati);
if (!$this->dati[$this->prefisso.$this->procedura]) $this->dati[$this->prefisso.$this->procedura]=array();
if (time()-@filemtime($this->get_nome_file_procedura())>3600) $this->check_scaduti_procedura();
//echo ""; print_r($this->get('GRAFICA'));exit;
return true;
}
function flush_procedura() {
if (!$this->modificate['procedura'][$this->prefisso.$this->procedura]) return true;
$temp=$this->dati[$this->prefisso.$this->procedura];
$fp=@fopen($this->get_nome_file_procedura(),'w+');
if(!$fp) return false;
@flock($fp, LOCK_EX);
$this->load_procedura($fp);
foreach ($this->modificate['procedura'][$this->prefisso.$this->procedura] as $chiave=>$segno)
{
if ($segno=='-') unset($this->dati[$this->prefisso.$this->procedura][$chiave]);
else $this->dati[$this->prefisso.$this->procedura][$chiave]=&$temp[$chiave];
}
$out=serialize($this->dati[$this->prefisso.$this->procedura]);
$ok=rewind($fp) && (fwrite($fp,$out)===strlen($out)) && ftruncate($fp,strlen($out));
@flock($fp, LOCK_UN);
@fclose($fp);
if ($ok) unset($this->modificate['procedura'][$this->prefisso.$this->procedura]);
else @unlink($this->get_nome_file_procedura());
return $ok;
}
function flush_general() {
if (!$this->modificate['general'][$this->prefisso]) return true;
$temp=$this->dati[$this->prefisso];
$fp=@fopen($this->get_nome_file_generale(),'w+');
@flock($fp, LOCK_EX);
$this->load_general($fp);
foreach ($this->modificate['general'][$this->prefisso] as $chiave=>$segno) {
if ($segno=='-') unset($this->dati[$this->prefisso][$chiave]);
else $this->dati[$this->prefisso][$chiave]=&$temp[$chiave];
}
$out=serialize($this->dati[$this->prefisso]);
$ok=@rewind($fp) && @fwrite($fp,$out)===strlen($out) && @ftruncate($fp,strlen($out));
@flock($fp, LOCK_UN);
@fclose($fp);
if (!$ok) @unlink($this->get_nome_file_generale());
else unset($this->modificate['general'][$this->prefisso]);
return $ok;
}
/** @ignore */
function check_scaduti_generale() {
foreach ( $this->dati[$this->prefisso] as $nome=>&$v ) $this->get_general($nome);
}
/** @ignore */
function get_nome_file_procedura() {
return "{$this->percorso}/{$this->prefisso}_".base64_encode($this->procedura).'.dat';
}
/** @ignore */
function check_scaduti_procedura() {
foreach ( $this->dati[$this->prefisso.$this->procedura] as $nome=>&$v ) $this->get($nome);
}
/** @ignore */
function get_nome_file_generale() {
return "{$this->percorso}/{$this->prefisso}.dat";
}
/**
* Salva i dati su disco, solo da quel momento diventano disponibili per gli altri script
* su PHP5 i dati si salvano in automatico anche al termine dello script, su PHP4 occorre invocarlo esplicitamente
*
* @param boolean $procedura salva i dati della procedura indicata nel costruttore
* @param boolean $general salva i dati generali
* @return boolean esito
*/
function flush($procedura=true, $general=true){
if ($procedura) $esito_procedura=$this->flush_procedura();
if ($general) $esito_general=$this->flush_general();
return $this->stato=(!$procedura || $esito_procedura) && (!$general || $esito_general);
}
function set($nome,$valore='',$forzaNulli=false,$timeOut=0) {
$this->modificate['procedura'][$this->prefisso.$this->procedura][$nome]='+';
$esito=mySessions::set($nome,$valore,$forzaNulli,$timeOut);
if(!$esito) $this->del($nome) ;
return $esito;
}
function del($nome) {
$this->modificate['procedura'][$this->prefisso.$this->procedura][$nome]='-';
return mySessions::del($nome);
}
function get_general($nome) {
if (!isset($this->dati[$this->prefisso])) $this->load_generale();
if (isset($this->dati[$this->prefisso][$nome]['Timeout']) &&
$this->dati[$this->prefisso][$nome]['Timeout']del_general($nome);
return @unserialize($this->dati[$this->prefisso][$nome]['Dati']);
}
function set_general($nome,$valore='',$forzaNulli=false,$timeOut=0) {
if (!isset($this->dati[$this->prefisso])) $this->load_general();
if ($nome && ($forzaNulli || ($valore!==null && $valore!=='' && $valore!==0)) && ($dato=@serialize($valore))!=='')
{$this->modificate['general'][$this->prefisso][$nome]='+';
$this->dati[$this->prefisso][$nome]['Dati']=$dato;
if ($timeOut) $this->dati[$this->prefisso][$nome]['Timeout']=time()+$timeOut;
return true;
}
return false;
}
function del_general($nome) {
if (!isset($this->dati[$this->prefisso])) $this->load_generale();
$this->modificate['general'][$this->prefisso][$nome]='-';
unset($this->dati[$this->prefisso][$nome]);
}
}
/**
* I dati vengono salvati sul file ma in RAM, quindi ancora più performante.
* Unico vincolo (oltre alla dimensione della memoria) è che sia attiva e funzionante l'estensione ZendCache dello Zend Server
* Il salvataggio è contestuale al set/unset quindi il metodo flush() è inutile.
*
* @package mySessions
*/
class myZendSessions extends myStorageSessions {
/**#@+ @ignore */
protected $prefisso='MZS';
protected function my_delete($k) {return @zend_shm_cache_delete($k); }
protected function my_store($k,&$v,$ttl=0) {return @zend_shm_cache_store($k,$v,$ttl); }
protected function my_get($k) {return @zend_shm_cache_fetch($k); }
function dels() {@zend_shm_cache_clear("{$this->prefisso}_{$this->procedura}");}
function is_available(){return is_callable('zend_shm_cache_store');}
/**#@-*/
/**
* Ottiene un lock se true lock ottenuto, false non ottenuto
* funziona solo se Zend_Cache prevede emulazione APC (come di default)
*
* @param string $nome_lock codice mnemonico lock
* @param int $attesa_max attesa massima in microsecondi , 0 non ha attesa
* @param int $timeout_naturale numero di secondi dopo di che il lock si rilascia ugualmente, se 0 non scade mai, attenzione!
* @return boolean
*/
function get_lock($nome_lock,$attesa_max=0,$timeout_naturale=0) {
$fine=microtime(1)+$attesa_max/1000000;
do {
$locked=@apc_add("{$this->prefisso}_$nome_lock",1,($timeout_naturale?$timeout_naturale:2592000));
} while (!$locked && microtime(1)<=$fine);
return $locked;
}
function release_lock($nome_lock) {@apc_delete("{$this->prefisso}_$nome_lock");}
function delete($k) {return @zend_shm_cache_delete($k);}
function flush() { }
}
/**
* I dati vengono salvati sul file ma in RAM, quindi ancora più performante.
* Unico vincolo (oltre alla dimensione della memoria) è che sia attiva e funzionante l'estensione wincache
* Il salvataggio è contestuale al set/unset quindi il metodo flush() è inutile.
*
* @link http://it2.php.net/manual/en/book.wincache.php Manuale Wincache
* @access public
* @package mySessions
*/
class myWincacheSessions extends MySessions {
/**#@+ @ignore */
protected $prefisso='MWCS';
protected function my_delete($k){return @wincache_ucache_delete($k); }
protected function my_get($k){ return @wincache_ucache_get($k); }
protected function my_store($k,&$v,$ttl=0){ return @wincache_ucache_set($k,$v,$ttl); }
/**#@-*/
/**
* Ottiene un lock se true lock ottenuto, false non ottenuto
*
* @param string $nome_lock codice mnemonico lock
* @param int $attesa_max attesa massima in microsecondi , 0 non ha attesa
* @param int $timeout_naturale numero di secondi dopo di che il lock si rilascia ugualmente, se 0 non scade mai, attenzione!
* @return boolean
*/
function get_lock($nome_lock,$attesa_max=0,$timeout_naturale=0) {
$fine=microtime(1)+$attesa_max/1000000;
do {
$locked=@wincache_ucache_add("{$this->prefisso}_$nome_lock",1,($timeout_naturale?$timeout_naturale:2592000));
} while (!$locked && microtime(1)<=$fine);
return $locked;
}
function release_lock($nome_lock) {
@wincache_ucache_delete("{$this->prefisso}_$nome_lock");
}
function is_available(){
return is_callable('wincache_ucache_info');
}
function get_status() {
return wincache_ucache_info('user');
}
function flush() {}
}
/**
* Classe astratta per la costruzione di mySession con funzionamento di storage
* I DATI SONO CONDIVISI TRA TUTTI GLI SCRIPT E NON LEGATI ALLA SESSSIONE UTENTE COME PER LA CLASSE MADRE
*
* @abstract
* @package mySessions
*/
abstract class myStorageSessions extends mySessions{
/**#@+ @ignore */
protected $compress=false;
function get_lock($nome_lock,$attesa_max=0,$timeout_naturale=0){throw new Exception ('Metodo da reimmplementare');}
function release_lock($nome_lock){throw new Exception ('Metodo da reimmplementare');}
function is_available(){throw new Exception ('Metodo da reimmplementare');}
function flush(){throw new Exception ('Metodo da reimmplementare');}
protected function my_compress(&$v) {
$v=serialize($v);
if(strlen($v)>512) $v=gzcompress($v,5);
}
protected function my_uncompress(&$v) {
if($v{0}=='x') {$x=gzuncompress($v);
if($x!==null) $v=$x;
}
$v=unserialize($v);
}
abstract protected function my_delete($k);
abstract protected function my_get($k);
abstract protected function my_store($k,&$v,$ttl=0);
function __destruct() {
$this->compress=false;
$this->my_store("{$this->prefisso}_{$this->prefisso}_nomi",self::$nomi);
$this->flush();
}
/**#@-*/
function __construct($procedura) {
if (!$procedura) {return;}
$this->procedura=$procedura;
if(!is_array(self::$nomi) && !$this->is_available()) self::$nomi=$this->my_get("{$this->prefisso}_{$this->prefisso}_nomi");
}
function set_general($nome,$valore='',$forzaNulli=false,$timeOut=0) {
if ($nome && ($forzaNulli || ($valore!==null && $valore!=='' && $valore!==0)))
{if($this->compress) $this->my_compress($valore);
$esito=$this->my_store("{$this->prefisso}_$nome",$valore,(int) $timeOut);
return $esito;
}
return false;
}
function get_general($nome) {
$valore=$this->my_get("{$this->prefisso}_$nome");
if($this->compress) $this->my_uncompress($valore);
return $valore;
}
function del_general($nome) {
return $this->my_delete("{$this->prefisso}_$nome");
}
function set($nome,$valore='',$forzaNulli=false,$timeOut=0) {
if ($nome && ($forzaNulli || ($valore!==null && $valore!=='' && $valore!==0)))
{if($this->compress) $this->my_compress($valore);
$esito=$this->my_store("{$this->prefisso}_{$this->procedura}::$nome",$valore,(int) $timeOut);
if($esito) self::$nomi[$nome]=1;
return $esito;
}
return false;
}
function &get($nome) {
$valore=$this->my_get("{$this->prefisso}_{$this->procedura}::$nome");
if($this->compress) $this->my_uncompress($valore);
return $valore;
}
function del($nome) {
unset(self::$nomi[$nome]);
return $this->MY_delete("{$this->prefisso}_{$this->procedura}::$nome");
}
/**
* Restituite lo stato compressione non ha effetto su myFileSessions
* @return boolean
*/
function get_compress_status($status) {
return $this->compress;
}
/**
* Imposta l'uso della compressione dei dati non ha effetto su myFileSessions
* @param 0..9 $status se -1 i dati non vengono compressi , altrimenti indica il fattore i compressione gzcompress
*/
function set_compress_status($status) {
if(is_callable('gzcompress')) $this->compress=$status;
return $this;
}
}
/**
* I dati vengono salvati sul file ma in RAM, quindi ancora più performante.
* Unico vincolo (oltre alla dimensione della memoria) è che sia attiva e funzionante l'estensione APC
* Il salvataggio è contestuale al set/unset quindi il metodo flush() è inutile.
*
* @link http:/http://www.php.net/manual/en/book.apc.php Manuale APC
* @access public
* @package mySessions
*/
class myAPCSessions extends myStorageSessions {
/**#@+ @ignore */
protected $prefisso='MAPCS';
protected function my_delete($k){return @apc_delete($k); }
protected function my_get($k){ return @apc_fetch($k); }
protected function my_store($k,&$v,$ttl=0){ return @apc_store($k,$v,$ttl); }
/**#@-*/
/**
* Ottiene un lock se true lock ottenuto, false non ottenuto
*
* @param string $nome_lock codice mnemonico lock
* @param int $attesa_max attesa massima in microsecondi , 0 non ha attesa
* @param int $timeout_naturale numero di secondi dopo di che il lock si rilascia ugualmente, se 0 non scade mai, attenzione!
* @return boolean
*/
function get_lock($nome_lock,$attesa_max=0,$timeout_naturale=0) {
$fine=microtime(1)+$attesa_max/1000000;
do {
$locked=@apc_add("{$this->prefisso}_$nome_lock",1,($timeout_naturale?$timeout_naturale:2592000));
} while (!$locked && microtime(1)<=$fine);
return $locked;
}
function is_available(){
return is_callable('apc_cache_info');
}
function release_lock($nome_lock) {
@apc_delete("{$this->prefisso}_$nome_lock");
}
function get_status() {
return apc_sma_info(true);
}
function flush() {}
}
/**
* Analoga alle MyFileSessions nei metodi e nel funzionamento,
* i dati però non vengono salvati sul file ma in RAM, quindi ancora più performante.
* Unico vincolo (oltre alla dimensione della memoria) è che sia attiva e funzionante l'estensione memcache
* Il salvataggio è contestuale al set/unset quindi il metodo flush() è inutile.
*
* @link http://it2.php.net/manual/it/ref.memcache.php Manuale memcache
* @access public
* @package mySessions
*/
class myMemcacheSessions extends myStorageSessions {
/**#@+ @ignore */
protected $prefisso='MMS',$maxSizeItem=1048000;
protected $memcache;protected static $memcaches=array();
/**#@-*/
/**
* Costruttore di classe
*
* @access public
* @param string $procedura
* @param string/array $server il nome (o i nomi) nel formato ip:porta:peso (quest'ultimo nel caso siano più server)
* @param object &$memcache è l'istanza di memcache creata oppure è l'eventuale istanza di memcache da utilizzare (va bene anche un'istanza di Memcached)
* @param boolean &$errore viene settato a true se c'è un'errore durante la connessione al server
*/
function __construct($procedura,$server='127.0.0.1:11211:0',&$memcache=null,&$errore=false)
{$k=sha1(serialize($server));
if(is_object($memcache)) $this->memcache=self::$memcaches[$k]=$memcache;
elseif(is_object(self::$memcaches[$k])) $this->memcache=self::$memcaches[$k];
else{
if(!is_array($server)) $server=array($server);
if(class_exists('Memcache'))
{$memcache=new Memcache;
foreach ($server as $srv) {
$srv=explode(':',$srv);
$memcache->addServer($srv[0],($srv[1]?$srv[1]:11211),true,1,($srv[2]?$srv[2]:1));
}
}
if(!is_object($this->memcache) && class_exists('Memcached'))
{$memcache=new Memcached($this->prefisso);
foreach ($server as $srv) {
$srv=explode(':',$srv);
$memcache->addServer($srv[0],($srv[1]?$srv[1]:11211),($srv[2]?$srv[2]:0));
}
}
if (@$memcache->getVersion()) $this->memcache=self::$memcaches[$k]=$memcache;
}
if(is_object($this->memcache)) parent::__construct($procedura);
}
function is_available(){
return is_object($this->memcache);
}
/** @ignore */
protected function my_delete($k){
if(!is_object($this->memcache)) return false;
if(!$this->maxSizeItem) return @$this->memcache->delete($k, 0);
do {$deleted=@$this->memcache->delete("$k$next",0);
$i++;
if($i) $next="/next~$i";
}while ($deleted);
return true;
}
/** @ignore */
protected function my_get($k){
if(!is_object($this->memcache)) return false;
if(!$this->maxSizeItem) return @$this->memcache->get($k);
$v='';
$keys=array();
do {$keys[]="$k$next";
if($i%5==1) { $vals=$this->real_get($keys);
$v.=implode('',$vals);
if(!$vals[$keys[count($keys)-1]]) break;
$keys=array();
}
$next="/next~".(++$i);
} while (true);
if(!$this->compress) return @unserialize($v);
return $v;
}
/**
* @ignore
*/
protected function my_store($k,&$to_store,$ttl=0){
if(!is_object($this->memcache)) return false;
if(!$this->compress) $to_store=serialize($to_store);
$esito=true;
do {echo " storing ",($i>0?"$k/next~$i":$k);
$esito=$esito && $this->real_store(($i>0?"$k/next~$i":$k), substr($to_store, $i*$this->maxSizeItem,$this->maxSizeItem),$ttl);
}while($esito && ++$i*$this->maxSizeItemreal_store('', $TO_STORE);
return $esito;
}
/** @ignore */
private function &real_get(array &$k){
if($this->memcache instanceof Memcache) return @$this->memcache->get($k);
if($this->memcache instanceof Memcached) return @$this->memcache->getMulti($k);
}
/** @ignore */
private function real_store($k,&$v,$ttl=0){
if($ttl>30*24*3600) $ttl=30*24*3600;
if($this->memcache instanceof Memcached) return @$this->memcache->set($k,$v,$ttl);
if($this->memcache instanceof Memcache) return @$this->memcache->set($k,$v,($this->maxSizeItem?0:MEMCACHE_COMPRESSED),$ttl);
}
/**
* Ottiene un lock se true lock ottenuto, false non ottenuto
*
* @param string $nome_lock codice mnemonico lock
* @param int $attesa_max attesa massima in microsecondi , 0 non ha attesa
* @param int $timeout_naturale numero di secondi dopo di che il lock si rilascia ugualmente, se 0 scade dopo 30 giorni (durata max per memcache), attenzione!
* @return boolean
*/
function get_lock($nome_lock,$attesa_max=0,$timeout_naturale=0) {
$fine=microtime(1)+$attesa_max/1000000;
do {
$locked=@$this->memcache->add("{$this->prefisso}_$nome_lock",1,0,($timeout_naturale?$timeout_naturale:2592000));
} while (!$locked && microtime(1)<=$fine);
return $locked;
}
function release_lock($nome_lock) {
@$this->memcache->delete("{$this->prefisso}_$nome_lock");
}
function get_status($type='') {
if(!$type) return $this->memcache->getStats();
else return $this->memcache->getExtendedStats($type);
}
function flush() {@$this->memcache->flush();}
}
abstract class myAutoSessions {
static function get_Istanza($procedura,
$options=array(
'myZendSessions'=>array(),
'myAPCSessions'=>array(),
'myWincacheSessions'=>array(),
'myMemcacheSessions'=>array('127.0.0.1:11211'),
'myFileSessions'=>array()
)
){
$test_fun=array(
'myapcsessions'=>'apc_cache_info',
'myzendsessions'=>'zend_shm_cache_store',
'mywincachesessions'=>'wincache_ucache_info'
);
foreach ($options as $class=>&$pars) {
$class=strtolower($class);
if(isset($test_fun[$class]) && !is_callable($test_fun[$class])) continue;
$rc = new ReflectionClass($class);
$obj=$rc->newInstanceArgs(array_merge(array($procedura) , (array) $pars));
if($obj->is_available()) return $obj;
unset($obj);unset($rc);
}
return false;
}
}
?>