Witam. Napisałem ostatnio własny mechanizm sesji, który korzysta z bazy i ciasteczek.
Oto kod:
<?php
class sessions extends dbTable {
public $_name = 'sessions'; //nazwa tabeli w bazie z sesjami
private $ua = null; //user_agent
private $ip = null; //remote_addr;
private $SID = null; //id sesji
private $vars = array(); //zmienne sesji protected $timeOut = 3600; //czas wygaśnięcia sesji w sekundach
private function __clone(){}
private static $instance = false; //zmienna instancji klasy
public function __construct(){
parent::__construct();
$this->ua = strtolower($_SERVER['HTTP_USER_AGENT']); $this->ip = $_SERVER['REMOTE_ADDR'];
$this->checkSession();
}
/*
zwraca instancję klasy. w przypadku kiedy nie istnieje tworzy ją
*/
public static function getInstance
() { if (!self::$instance) {
self::$instance = new sessions();
}
return self::$instance;
}
/*
zwraca nazwę przeglądarki
*/
public function getBrowser(){
'mozilla'=>'mozilla',
'opera'=>'opera',
'msie'=>'msie',
'netscape'=>'netscape',
'konqueror'=>'konqueror',
'galeon'=>'galeon',
'firefox'=>'firefox',
'netsprint'=>'netsprint',
'firebird'=>'firebird',
'links'=>'links',
'lynks'=>'lynks',
'meleon'=>'kmeleon',
'dillo'=>'dillo',
'omniweb'=>'omniweb',
'avant'=>'avant',
'myie2'=>'myie2',
'seamonkey'=>'seamonkey',
'maxthon'=>'maxthon',
'chrome'=>'chrome',
'safari'=>'safari');
foreach($browsers as $browser=>$name){
if(strpos($this->ua, $browser) !== false){ return $name;
}
return 'unknown';
}
}
/*
zwraca system operacyjny klienta
*/
public function getOS(){
'windows'=>array(
'nt 4.0'=>'windows98',
'nt 5.0'=>'windows2000',
'nt 5.1'=>'windowsXP',
'nt 5.2'=>'windowsXP',
'nt 6.0'=>'windowsVista',
'nt 6.1'=>'windows7',
'nt 6.2'=>'windows8',
'default'=>'windows'
),
'linux'=>array(
'suse'=>'suse',
'knoppix'=>'knoppix',
'turbolinux'=>'turbolinux',
'slackware'=>'slackware',
'gentoo'=>'gentoo',
'lycoris'=>'lycoris',
'debian'=>'debian',
'redhat'=>'redhat',
'archlinux'=>'arch',
'kubuntu'=>'kubuntu',
'ubuntu'=>'ubuntu',
'mandriva'=>'mandriva',
'slax'=>'slax',
'mint'=>'mint',
'centos'=>'centos',
'fedora'=>'fedora',
'openbsd'=>'openbsd',
'netbsd'=>'netbsd',
'pc-bsd'=>'pcbsd',
'bsd'=>'freebsd',
'default'=>'linux'
));
foreach($OSs as $OS=>$system){
foreach($system as $os2=>$name){
if(strpos($this->ua, $os2) !== false){ return $name;
}
}
if(strpos($this->ua, $OS) !== false){ return $system['default'];
}
else{
continue;
}
}
}
/*
zwraca ip klienta
*/
public function getIP(){
return $this->ip;
}
/*
inicjuje zmienną lub zmienia jej wartość
*/
public function _set($name, $value){
return ($this->vars[$name]=$value) ? true : false;
}
/*
zwraca wartość zmiennej
*/
public function _get($name){
return (isSet($this->vars[$name])==true) ?
$this->vars[$name] : false; }
/*
usuwa zmienna
*/
public function _unset($name){
unset($this->vars[$name]); }
/*
zwraca zmienne sesji
*/
public function _getAll(){
return $this->vars;
}
/*
generuje id sesji
*/
public function generateSID(){
}
/*
rozpoczyna sesje, tworzy ciasteczko i nowy wpis w bazie
*/
public function sessionStart(){
$this->generateSID();
$sid = $this->SID;
$timeOut = time()+$this->timeOut; setCookie('RPFSID', $sid, $timeOut, '/szp/', ''); $_COOKIE['RPFSID'] = $sid;
'ip'=>$this->ip,
'przegladarka'=>$this->getBrowser(),
'system'=>$this->getOS(),
'zmienne'=>'',
'czasWygasniecia'=>$timeOut,
'idSesji'=>$sid
);
return $this->insert($data, $this->_name);
}
/*
niszczy sesje
*/
public function sessionDestroy(){
$this->where('ip = ?', $this->ip)->where('idSesji = ?', $this->SID)->cache(false)->delete($this->_name);
}
/*
sprawdza czy sesja jest poprawna, jeśli jest to sprawdza poprawność SID i przypisuje zmienne, jeśli nie to tworzy nową
*/
public function checkSession(){
if($this->sessionExist() == false){
if($this->sessionStart() === false){
return false;
}
}
$result = $this->select()->from($this->_name)->where('ip = ?', $this->ip)->cache(false)->sql()->fetchObject();
$result = $result[0];
if($result->przegladarka == $this->getBrowser() && $result->system == $this->getOS()){
$this->SID = $result->idSesji;
$this->refreshSession();
return true;
}
return false;
}
/*
sprawdza czy sesja istnieje
*/
public function sessionExist(){
$result = $this->select()->from()->where('ip = ?', $this->ip)->cache(false)->sql()->fetchObject();
if(empty($result) == false && isSet($_COOKIE['RPFSID']) == true && $result[0
]->idSesji == $_COOKIE['RPFSID']){ return true;
}
if(empty($result) == false || $result->czasWygasniecia < time()){ $this->where('ip = ?', $this->ip)->delete($this->_name);
}
return false;
}
/*
zapisuje zmienne do bazy
*/
public function saveVars(){
return $this->where('ip = ?', $this->ip)->where('idSesji = ?', $this->SID)->cache(false)->update(array('zmienne'=>serialize
($this->vars)), $this->_name
); }
/*
odświeża czas wygaśnięcia sesji
*/
public function refreshSession(){
$timeOut = time() + $this->timeOut; $this->where('ip = ?', $this->ip)->where('idSesji = ?', $this->SID)->cache(false)->update(array('czasWygasniecia'=>$timeOut), $this->_name
, true); }
public function _destruct(){
parent::__destruct();
$this->saveVars();
}
}
?>
Problem polega na tym, że raz mogę się zalogować, zmienne są w bazie, ciasteczko istnieje, odświeżając stronę sesja nadal jest, ale gdy przechodzę na inna podstronę to sesja ginie, zmienia się id sesji, znikają zmienne etc. Dziwne jest to, że raz działa, a raz nie, raz się loguje za 1 razem, nieraz za n-tym. Zauważyłem również, że usunięcie rekordu z tabeli sesji i ręczne usunięcie ciasteczek poprawia sytuację w ten sposób, że normalnie się loguje i poruszam po stronie, sesja nie ginie. Ale gdy tylko się wyloguje i chcę od nowa zalogować problem powraca. Może wiecie co jest źle zrobione, bo ja już się z tym męczę od paru dni i nic...