补充$ _SESSION变量

时间:2013-11-23 15:14:31

标签: php session mariadb php-5.4

我想知道是否有可能取代$ _SESSION。我想创建一个使用$ _SESSION在我的数据库中记录会话的系统,如下所示:

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

如果我的课程会话不可用或网站管理员禁用,我希望我的系统完全透明且功能正常。

感谢您的帮助。

1 个答案:

答案 0 :(得分: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 在这里,你可以只使用两个查询 - 会话读取和会话写入。