2013-11-23 6 views
0

Я хотел бы знать, можно ли вытеснить $ _SESSION. Я хотел бы создать систему, которая использует $ _SESSION для записи своих сессий в моей базе данных, как это:

$_SESSION['identifier'] = 'value'; // Perform insert/update on my DBMS 
echo $_SESSION['identifier']; // Perform select on my DBMS 

Я хотел бы моя система полностью прозрачна и функциональная, если мой класс сеанс недоступен или отключен сайт администратор.

Благодарим за помощь.

ответ

0

Вот пример кода:

$sess = new sess(); 

session_start(); 
$_SESSION =& $sess; 

//test 
$_SESSION['value'] = 'ccc'; 

some_test_func(); 
function some_test_func() { 
//test again in different scope 
$_SESSION['anotehr_value'] = 444; 
} 


class sess implements \Iterator, \ArrayAccess, \Countable 
{ 

    protected $session_data; 

    public final function rewind() { 
     reset($this->session_data); 
    } 

    public final function current() { 
     $var = current($this->session_data); 
     return $var; 
    } 

    public final function key() { 
     $var = key($this->session_data); 
     return $var; 
    } 

    public final function next() { 
     $var = next($this->session_data); 
     return $var; 
    } 

    public final function valid() { 
     $var = $this->current() !== false; 
     return $var; 
    } 

    public final function offsetExists($offset) { 
     //Database query comes here (SELECT) 
     print 'SELECT var_value FROM session_data WHERE var_name = :offset AND session_id = :session_id'; 
     $session_id = session_id(); 
     return isset($this->session_data[$offset]); 
    } 

    public final function offsetGet($offset) { 
     //Database query comes here (SELECT) 
     print 'SELECT var_value FROM session_data WHERE var_name = :offset AND session_id = :session_id'; 
     $session_id = session_id(); 
     return $this->session_data[$offset]; 
    } 

    public final function offsetSet($offset,$value) { 
     //Database query comes here (REPLACE by primary key) 
     print 'REPLACE INTO session_data (session_id, var_name, var_value) VALUES (:session_id, :offset, :value)'; 
     $session_id = session_id(); 
     $this->session_data[$offset] = $value; 
    } 

    public final function offsetUnset($offset) { 
     //Database query comes here (DELETE) 
     print 'DELETE FROM session_data WHERE var_name = :offset AND session_id = :session_id'; 
     $session_id = session_id(); 
     unset($this->session_data[$offset]); 
    } 

    public final function count() { 
     return count($this->session_data); 
    } 
} 

Вы можете расширить его, добавив также перегрузки. Вы можете использовать $ session_data как кешированную копию или использовать все запросы (которые, если можно, вам следует избегать). В общем случае я бы рекомендовал не делать запрос против каждого изменения сессии (будет много записей в БД). Возможно, вы делаете это, чтобы избежать перезаписывания сеансов, но для этого вы можете использовать механизм блокировки для сериализации всего запроса с тем же session_id. Другая причина, по которой я бы избегал этого, потому что эта строка: $ _SESSION = & $ sess; может не работать в некоторой будущей версии PHP. (Я тестировал это на php 5.3.20).

Другая проблема в том, что другой человек в будущем может просто использовать ваш код, даже не подозревая, что $ _SESSION делает на заднем плане ... Вы должны явно документировать это поведение.

P.S. или, может быть, вы просто хотите сохранить сеансы в базе данных. Тогда вы должны посмотреть на http://php.net/manual/en/function.session-set-save-handler.php Здесь вы можете уйти с двумя запросами - при чтении сеанса и при записи на сессии.

+0

Отлично, спасибо! – Gecko