Hallo,
ich musste gerade feststellen das der SessionHandler irgendwie nur maximal 1 Session speichert.
Habe die Seite in 2 verschiedene Browser auf (jeweils mit nem anderen User eingeloggt) und sobald der eine Browser die Seite neu geladen hat, ist die andere Sitzung aus Memcached raus.
Die entsprechende Klasse
Ich habe jetzt schon einige Tests gemacht aber ich komme dem Fehler nicht auf die Spur
Aber da oben in der switch()-Anweisung mit new memSess() der Handler ja initialisiert und gesetzt wird und in der nächsten Zeile wird die Session erstellt und gleich darauf ist die Session dann leer. Also kann es doch garnicht anders sein als das die vorherige Session schlicht und ergreifend überschrieben wird (und somit immer die zuletzt genutzte vorhanden ist).
Ein Test in WebSocket legt dies auch nahe, denn dort wird beim verbinden die Session aus Memcache geladen und validiert und hier bekomme ich ebenfalls die Meldung das diese nicht existiert.
Nun ist die Frage wo der Fehler ist, denn die write()-Funktion funktioniert ja sonst würde es bei jedem Laden/connect eine leere Sitzung geben, dies ist aber ja nur der Fall wenn eine andere session_ID die Seite lädt (kickt die alte raus).
Ich hoffe Jemand hat damit schon mal Erfahrung gemacht und kann mir weiterhelfen!
LG: Paykoman
ich musste gerade feststellen das der SessionHandler irgendwie nur maximal 1 Session speichert.
Habe die Seite in 2 verschiedene Browser auf (jeweils mit nem anderen User eingeloggt) und sobald der eine Browser die Seite neu geladen hat, ist die andere Sitzung aus Memcached raus.
PHP-Code:
// Initzialisierung der Session
header('x-xss-protection: 1; mode=block');
header('x-content-type-options: nosniff');
header('x-frame-options: SAMEORIGIN');
header('Cache-Control: public, max-age=31536000');
// Session Settings
ini_set('session.use_cookies', true); // Cookies are safer
ini_set('session.cookie_domain', self::$domain);
ini_set('session.use_only_cookies', true); // not all user allow cookies
ini_set('session.cookie_secure', true); // only on https will cookies be send
ini_set('session.cookie_httponly', true); // JS can not acces to session-Cookie
// ini_set("session.hash_function", "1"); // removed on PHP 7.1.0
ini_set('session.sid_length', 22); // PHP 7.1.0 >
ini_set('session.sid_bits_per_character', 6);
ini_set('session.cookie_lifetime', '0'); // Cookie-Lebensdauer, '0' = "bis der Browser geschlossen wird
ini_set('session.gc_maxlifetime', 10800); // Ab wann Sessions als 'garbage' ('Müll') betrachtet und ggf. entsorgt werden könnten
// ini_set('session.gc_probability', 1);
// ini_set('session.gc_divisor', 1);
session_cache_limiter('nocache');
session_name('ws'); // Don`t change !!!
switch( $sessMode ){ // the key contains the mode
case 'memcache':
case 'memcached':
session_set_save_handler(new memSess($sessMode, $servers, array_shift($settings)), true); // initalisiert den Handler
break;
case 'files':
new fileSess();
break;
default:
// All other use default php session - don`t use a interface
// ini_set('session.gc_maxlifetime', self::$lifeTime);
}
session_start();
eHandler::datas('sess', $_SESSION);
PHP-Code:
class memSess implements SessionHandlerInterface{
private $memcache = null;
private $mode;
private $quitFunc;
private $pref;
private $reedCheck;
public function __construct($mode, $servers, $pref){
// eHandler::datas('memSess', [$mode, session::$lifeTime]);
// register_shutdown_function('session_write_close');
$this->mode = $mode;
$this->pref = $pref;
$this->memcache = new $mode;
if( $mode == 'memcached' ){
$this->reedCheck = null; // memcached return null on not found keys
$this->quitFunc = 'quit'; // memcached use quit()
$this->memcache->addServers($servers);
}else{
$this->reedCheck = false; // memcache return false on not found keys
$this->quitFunc = 'close'; // memcache use close()
foreach( $servers as $server ){ if( count($server) == 2 ){ self::$cacheInstance->addServer($server[0], $server[1]); }else{ self::$cacheInstance->addServer($server[0], $server[1], $server[2]); } }
}
}
/**
* Destructor
*/
public function __destruct(){
$this->memcache->{$this->quitFunc}();
}
/**
* Open the session handler, set the lifetime at session.gc_maxlifetime
* @return boolean True if everything succeed
*/
public function open($save_path, $session_name){
return true;
}
/**
* Read the id
* @param string $id The SESSID to search for
* @return string The session saved previously
*/
public function read_err($id){
$_SESSION = json_decode($this->memcache->get($this->pref.$id), true);
// if($_SESSION === $this->reedCheck){ $_SESSION = []; }
return '';
}
public function read($id){
$tmp = $_SESSION;
$_SESSION = json_decode($this->memcache->get($this->pref.$id), true);
if( !empty($_SESSION) && $_SESSION != null ){
$new_data = session_encode();
$_SESSION = $tmp;
return $new_data;
}else{
return '';
}
}
/**
* Write the session data, convert to json before storing
* @param string $id The SESSID to save
* @param string $data The data to store, already serialized by PHP
* @return boolean True if memcached was able to write the session data
*/
public function write($id, $data){
$tmp = $_SESSION;
session_decode($data);
$new_data = $_SESSION;
$_SESSION = $tmp;
return $this->{'write'.ucfirst($this->mode)}($id, $new_data);
}
private function writeMemcache($id, $new_data){ return $this->memcache->set($this->pref.$id, json_encode($new_data), 0, session::$lifeTime); }
private function writeMemcached($id, $new_data){ return $this->memcache->set($this->pref.$id, json_encode($new_data), session::$lifeTime); }
/**
* Delete object in session. memache and memcached both the same function
* @param string $id The SESSID to delete
* @return boolean True if memcached was able delete session data
*/
public function destroy($id){
return ( $this->memcache->get($this->pref.$id) === false ) ? true : $this->memcache->delete($this->pref.$id, 0);
}
/**
* Close gc
* @return boolean Always true
*/
public function gc($maxlifetime){
return true;
}
/**
* Close session, quit for memcached
* @return boolean Always true
*/
public function close(){
return ( $this->mode == 'memcached' ) ? $this->memcache->quit() : true;
}
}
Aber da oben in der switch()-Anweisung mit new memSess() der Handler ja initialisiert und gesetzt wird und in der nächsten Zeile wird die Session erstellt und gleich darauf ist die Session dann leer. Also kann es doch garnicht anders sein als das die vorherige Session schlicht und ergreifend überschrieben wird (und somit immer die zuletzt genutzte vorhanden ist).
Ein Test in WebSocket legt dies auch nahe, denn dort wird beim verbinden die Session aus Memcache geladen und validiert und hier bekomme ich ebenfalls die Meldung das diese nicht existiert.
Nun ist die Frage wo der Fehler ist, denn die write()-Funktion funktioniert ja sonst würde es bei jedem Laden/connect eine leere Sitzung geben, dies ist aber ja nur der Fall wenn eine andere session_ID die Seite lädt (kickt die alte raus).
Ich hoffe Jemand hat damit schon mal Erfahrung gemacht und kann mir weiterhelfen!
LG: Paykoman
Kommentar