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', $sessionId, PDO::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', $sessionId, PDO::PARAM_STR);
$stmt->bindValue(':session_data', $data, PDO::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', $sessionId, PDO::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);}