Doskonale Cię rozumiem, ale ja ostatnio non stop siedze i czytam

Nie miałbym problemów, jakbym sie nie uczepił rozwiązania przedstawionego w książce PHP5, Zaawansowane programowanie. Nadal uważam, że jest ono dobre, ale troche zakręcone.
Napisałem więc raczej prosty session handler. Lekkie modyfikacje, zeby był wygodniejszy. Kod poniżej:
<?php
class NotLoggedInSessionException extends Exception
{
}
class Session
{
private $_oDatabase;
private $_sPHPSessionId;
private $_iNativeSessionId;
private $_iSessionLifespan = 3600;
private $_iSessionTimeout = 60;
private $_iUserId;
private $_bIsLoggedIn;
private function __construct()
{
$this->_oDatabase = Database::getInstance();
$this->_bIsLoggedIn = false;
(
array(&$this, '_sessionOpen'), array(&$this, '_sessionClose'), array(&$this, '_sessionRead'), array(&$this, '_sessionWrite'), array(&$this, '_sessionDestroy'), array(&$this, '_sessionGC') );
try
{
$this->_sessionGC();
$this->_checkForActiveSession();
}
catch (Exception $oException)
{
throw $oException;
}
}
public static function getInstance
() {
if(!isset(self::$_oInstance)) {
$sClassName = __CLASS__;
self::$_oInstance = new $sClassName;
}
return self::$_oInstance;
}
public function _sessionOpen($sSavePath, $sSessionName)
{
return true;
}
public function _sessionRead($sPHPSessionId)
{
try
{
if(!$this->_isSession())
$this->_createNewSession($sPHPSessionId);
$sQuery = 'SELECT id, logged_in, user_id, vars
FROM session
WHERE phpsessid = "'.$sPHPSessionId.'"';
$this->_oDatabase->query($sQuery);
$aRow = $this->_oDatabase->fetch();
$this->_iNativeSessionId = $aRow['id'];
$this->_bLoggedIn = $aRow['logged_in'];
$this->_iUserId = $aRow['user_id'];
}
catch (Exception $oException)
{
throw $oException;
}
return $aRow['vars'];
}
public function _sessionWrite($sPHPSessionId, $sData)
{
$aToUpdate[] = array('vars', $sData);
try
{
$this->_oDatabase->update('session', $aToUpdate, 'phpsessid = "'.$this->_sPHPSessionId.'"');
}
catch (Exception $oException)
{
return false;
}
return true;
}
public function _sessionDestroy($sPHPSessionId)
{
$sQuery = 'DELETE FROM session
WHERE phpsessid = "'.$sPHPSessionId.'"';
try
{
$this->_oDatabase->query($sQuery);
}
catch (Exception $oException)
{
throw $oException;
}
return true;
}
public function _sessionGC($iMaxLifeTime = null)
{
$sQuery = 'DELETE FROM session
WHERE
((now() - start) > '.$this->_iSessionLifespan.') OR
((now() - last_activity) > '.$this->_iSessionTimeout.')';
try
{
$this->_oDatabase->query($sQuery);
}
catch (Exception $oException)
{
throw $oException;
}
return true;
}
public function _sessionClose()
{
return true;
}
private function _updateSession()
{
if(isset($this->_iNativeSessionId
)) {
$aToUpdate[] = array('last_activity', 'now()', false);
try
{
$this->_oDatabase->update('session', $aToUpdate, 'id = "'.$this->_iNativeSessionId.'"');
}
catch (Exception $oException)
{
throw $oException;
}
}
}
private function _isSession()
{
if(isset($this->_iNativeSessionId
)) return true;
else
return false;
}
private function _createNewSession($sPHPSessionId)
{
$sUserAgent = $_SERVER['HTTP_USER_AGENT'];
$aToInsert[] = array('phpsessid', $sPHPSessionId); $aToInsert[] = array('start', 'now()', false); $aToInsert[] = array('user_agent', $sUserAgent);
try
{
$this->_oDatabase->insert('session', $aToInsert);
$sQuery = 'SELECT id FROM session WHERE phpsessid = "'.$this->_sPHPSessionId.'"';
$this->_oDatabase->query($sQuery);
$aRow = $this->_oDatabase->fetch();
$this->_iNativeSessionId = $aRow['id'];
$this->_sPHPSessionId = $sPHPSessionId;
}
catch (Exception $oException)
{
throw $oException;
}
}
private function _checkForActiveSession()
{
$sUserAgent = $_SERVER['HTTP_USER_AGENT'];
if(!empty($_COOKIE['PHPSESSID'])) {
$this->_sPHPSessionId = $_COOKIE['PHPSESSID'];
$sQuery = 'SELECT id
FROM session
WHERE
phpsessid = "'.$this->_sPHPSessionId.'" AND
(
(now() - start) < '.$this->_iSessionLifespan.' AND
user_agent = "'.$sUserAgent.'" AND
(now() - last_activity) <= '.$this->_iSessionTimeout.'
) OR
last_activity IS NULL';
try
{
$this->_oDatabase->query($sQuery);
if($this->_oDatabase->numRows() === 0)
{
unset($_COOKIE['PHPSESSID']); // session is not valid or actual }
else
{
$aRow = $this->_oDatabase->fetch();
$this->_iNativeSessionId = $aRow['id'];
$this->_updateSession();
}
}
catch (Exception $oException)
{
throw $oException;
}
}
}
public function isLoggedIn()
{
return $this->_bIsLoggedIn;
}
public function getUserId()
{
if($this->isLoggedIn())
return $this->_iUserId;
}
public function getUserObject()
{
if($this->isLoggedIn())
{
try
{
$oUser = new User($this->getUserId());
return $oUser;
}
catch (Exception $oException)
{
throw $oException;
}
}
else
throw new SessionException('Can not return object. User was not logged in');
}
public function login($sLogin, $sPlainPassword)
{
$sPassword = md5($sPlainPassword);
$sQuery = 'SELECT id FROM users
WHERE
login = "'.$sLogin.'" AND
password = "'.$sPassword.'"';
try
{
$this->_oDatabase->query($sQuery);
if($this->_oDatabase->numRows() == 1)
{
$aUser = $this->_oDatabase->fetch();
$this->_iUserId = $aUser['id'];
$aToUodate[] = array('logged_in', 'true'); $aToUodate[] = array('user_id', $this->_iUserId
);
$this->_oDatabase->update('session', $aToUodate, 'id = "'.$this->_iNativeSessionId.'"');
$this->_bIsLoggedIn = true;
return true;
}
}
catch (Exception $oException)
{
throw $oException;
}
}
public static function logout
() {
if($this->isLoggedIn())
{
$aToUodate[] = array('logged_in', false); $aToUodate[] = array('user_id', 0
);
try
{
$this->_oDatabase->update('session', $aToUodate, 'id = "'.$this->_iNativeSessionId.'"');
$this->_bIsLoggedIn = false;
return true;
}
catch (Exception $oException)
{
throw $oException;
}
}
}
}
?>
Przepraszam, że bez komentarzy, ale zamieszczam opis metod:
Konstruktor: sprząta stare sesje. Wywoluje metodę _checkForActivesession a następnie uruchamia sesję.
_checkForActivesession: sprawdza, czy użytkownik jest w trakcje sesji - na podstawie ciasteczka. Pobiera id sesji z ciastka i sprawdza w bazie czy jest jeszcze prawdziwa. Jezeli nie, usuwa ciastko. Jezeli sesja jest poprawna - odswieza jej czas metoda _updateSession.
_sessionRead: wywoływana przez php. Sprawdza czy, jest sesja (jeżeli poprzednia metoda stwierdziała, że sesja jest poprawna, to także ustawiła id sesji). Jeżeli nie - tworzy nową za pomocą metody _createNewSession. Dalej pobiera dane sesji z bazy, ustawia id uzytkownika i inne dane, a następnie zwraca zmienne sesji.
_sessionWrite: zapisauje zmienne sesji w bazie.
login, logout, getUserObject to dodane przeze mnie metody, aby łatwiej zarządzać sesją

CZekam na Wasze komentarze.
Pozdrawiam, Adrian.