Вот пример кода:
$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 Здесь вы можете уйти с двумя запросами - при чтении сеанса и при записи на сессии.
Отлично, спасибо! – Gecko