Ciao a tutti!


ho un problema bizzarro con la funzione session_regenerate_id(true).
Premetto che la gestione delle sessioni è gestita tramite database mysql. (vedi codice allegato)


Il fatto è che funziona perfettamente:
se la sessione non esiste, viene creato il cookie con l'id di sessione e tutti i dati vengono correttamente inseriti sul db.
Se la sessione esiste, regenerate_session_id(true) genera una nuova id e i dati vengono aggiornati.


Il problema si verifica solo quando viene cliccato più volte (velocemente) il tasto refresh: l'id di sessione viene aggiornato, ma al contempo vengono creati anche altri record.
Vengono insomma generate una serie di sessioni orfane; valide ma che non corrispondono all'id del cookie e dunque inutili per l'utente.
Cliccando refresh più lentamente il problema non si pone.


Immagino dunque che la funzione session_regenerate_id(true) vada a lavorare in una maniera del genere (vado per supposizioni):


$id=session_id();//recupera l'id dal cookie
$data=read($id);//legge i dati dal db
$id2=...//genera una nuova id
write($id2,$data); //scrive la nuova id e i vecchi dati sul db


destroy($id);//cancella la vecchia sessione dal db e uccide il cookie
session_start(); //avvia una nuova sessione
session_id($id2) //collega l'id del record sul db alla nuova sessione


Arrivato a questo punto, mi sono fatto due idee:


1) non ho capito nulla di come funziona questa funzione.
2) il refresh compulsivo impedisce allo script di completare il suo ciclo.


Io proprio non ci arrivo. Qualcuno ci capisce qualcosa?



Codice PHP:

//registro le funzioni
session_set_save_handler(
 
                         array(
self::$session_handler'open'),
                         array(
self::$session_handler'close'),
                         array(
self::$session_handler'read'),
                         array(
self::$session_handler'write'),
                         array(
self::$session_handler'destroy'),
                         array(
self::$session_handler'gc')
                         );
 
 
//Nel dettaglio qui di seguito
 
public function open($sessionId){
 
if(
$this->connect()){return true;}
return 
false;
}
 
 
public function 
read($sessionId) {
 
$stmt=self::$_mysql->prepare("SELECT session_data FROM session where session_id = :session_id");
$stmt->bindValue(':session_id'$sessionIdPDO::PARAM_STR);
if(
$stmt->execute()){
$data $stmt->fetchColumn();
$stmt->closeCursor();
return 
$data;
}
return 
false;
}
 
public function 
write($sessionId$data) {
 
$stmt=self::$_mysql->prepare("REPLACE INTO session SET session_id = :session_id, session_data = :session_data, session_lastaccess = NOW()");
$stmt->bindValue(':session_id'$sessionIdPDO::PARAM_STR);
$stmt->bindValue(':session_data'$dataPDO::PARAM_STR);
if(
$stmt->execute()){return true;}
return 
false;
}
 
public function 
close(){
 
if(
$this->disconnect()){return true;}
return 
false;
}
 
 
public function 
destroy($sessionId) {
 
$stmt=self::$_mysql->prepare("DELETE FROM session WHERE session_id = :session_id");
$stmt->bindValue(':session_id'$sessionIdPDO::PARAM_STR);
setcookie(session_name(), ""time() - 3600);
if(
$stmt->execute()){return true;}
return 
false;
}
 
 
public function 
gc($lifetime) {
$stmt=self::$_mysql->prepare("DELETE FROM session WHERE session_lastaccess < DATE_SUB(NOW(), INTERVAL " $lifetime " SECOND)");
if(
$stmt->execute()){return true;}
return 
false;
}
 
 
//Nella pagina principale, per verificare il corretto funzionamento dello script ho messo questo codice:
 
session_start();
if(!
$_SESSION['user']){
$_SESSION['user']='kikko99';
$_SESSION['name']='cristian';
$_SESSION['mail']='cri89@kij.com';
}
else{
session_regenerate_id(true);}