【问题标题】:Fill PHP Sessions with default data使用默认数据填充 PHP 会话
【发布时间】:2014-05-23 19:28:49
【问题描述】:

我目前正在从头开始构建一个小网站。我使用自定义 SessionHandler 将我的会话存储在似乎工作正常的数据库中。因此,一旦用户登录,我就可以将相关信息(例如语言)存储在会话数据中。

但是,我还想为(尚未)登录的用户存储某些数据 - 再次主要是所选语言,还有一些其他内容。为了保持干净,我想在一个地方设置所有这些标准值,只要有一个没有有效登录的会话。

最好的地方显然应该是我的处理程序,但是我不确定要使用哪个函数以及如何在其中获取我的数据。我已经附上了下面代码的重要部分。

我确信有一个简单的解决方案,但到目前为止我还没有做到。而且这对谷歌来说也是一个可怕的问题..

感谢您的帮助!

public function __construct() {

    $this->databaseController = new DatabaseController();

    ini_set('session.gc_maxlifetime', SESSION_MAX_LIFETIME);
    ini_set('session.gc_probability', 1);
    ini_set('session.gc_divisor', 100);

    session_set_save_handler(
        array($this, "_open"),
        array($this, "_close"),
        array($this, "_read"),
        array($this, "_write"),
        array($this, "_destroy"),
        array($this, "_gc")
    );
}

public function _open() {
    return $this->databaseController->check();
}

public function _close() {
    return $this->databaseController->close();
}

public function _read($id) {
    $result = $this->databaseController->getFirstRow("SELECT sessionData FROM bf1_sessions WHERE sessionID = '".mysql_real_escape_string($id)."'");

    if (!empty($result['sessionData'])) {
        return $result['sessionData'];
    }
    else {
        return '';
    }
}

public function _write($id, $data) {
    $access = time();
    $result = $this->databaseController->executeQuery("REPLACE INTO bf1_sessions (sessionID, sessionAccess, sessionData) VALUES ('".mysql_real_escape_string($id)."', '".intval($access)."', '".mysql_real_escape_string($data)."')");
    return $result;
}

【问题讨论】:

    标签: php database session


    【解决方案1】:

    由于我从未真正使用过自定义会话处理程序,因此我不得不阅读一下文档。这将是更多的伪代码,但它应该让你朝着正确的方向前进。任何时候你开始一个会话,它都会首先调用open(),然后是read(string $sessionId)。您当前正在从数据库中选择会话数据并返回序列化数据或空白字符串(您应该这样做)。您应该能够返回默认数据的序列化字符串,而不是返回空白字符串。

    public function _read($id) {
        $result = $this->databaseController->getFirstRow("SELECT sessionData FROM bf1_sessions WHERE sessionID = '".mysql_real_escape_string($id)."'");
    
        if (!empty($result['sessionData'])) {
            return $result['sessionData'];
        }
        else {
            return serialize(array(
                'foo' => 'bar',
                'test' => 123
            ));
        }
    }
    

    请注意,上述操作可能无法完全按预期工作。我假设序列化数据是一个简单的键/值对数组,就像我上面的例子一样。此外,由于session_set_save_handler() 文档中的以下通知,serialize() 可能也不会完全按照您的预期执行:

    虽然数据看起来类似于 serialize(),但请注意它是在 session.serialize_handler ini 设置中指定的不同格式。

    最后一个想法:您实际上不需要将此默认数据写入数据库,因为每次保存/关闭会话时write($sessionId, $data) 都会使用 all 数据调用(而不是只是变化)。因此,您应该可以在read() 上返回默认数据并在调用write() 时保存所有内容。我只是提到这一点,因为有一个机会会发生一些奇怪的事情,你可能实际上需要INSERT INTO 默认数据,然后才能在你的read() 函数中返回它.如果您在执行此操作时遇到任何问题,请发表评论。


    链接:

    【讨论】:

    • 方法名称有 _ 因为我从教程中复制了部分 - 我现在删除了。
    • 您的功能与我目前想出的功能非常接近。但是它不起作用,因为 read() 方法不需要数据数组的键,而是读取该数组的会话 ID。我会继续努力想办法让它发挥作用。
    • 您需要更好地解释当前方法的作用以及 'sessionData' 包含的内容,而不是盲目地给我的答案 -1。
    • 我没有否决您的回答 - 我什至没有足够的声誉来使用该功能。我目前已经搁置了这个问题,我正在尝试弄清楚是否可以在不使用默认数据的情况下解决它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-19
    • 1970-01-01
    • 2018-11-30
    • 1970-01-01
    • 2015-11-27
    • 2020-05-26
    • 1970-01-01
    相关资源
    最近更新 更多