PHP自定义会话ID,优化版本

时间:2012-10-16 08:22:32

标签: php session

我想实现一个PHP自定义会话ID,同时避免不必要地调用session_start()

基本上,一个简单的算法是

session_start();
if ( ! isset( $_SESSION['MyStuff'] )) {
  session_write_close();
  session_id( generate_my_id() );
  session_start();
}

$_SESSION['MyStuff'] = some stuff...;

如果会话已过期或首先不存在,则第一个session_start()将创建自己的ID并将cookie发送到浏览器。然后会话结束,另一个会话被创建,另一个cookie发送(加上创建和关闭会话文件的开销)。

另一种解决方案是测试PHPSESSID cookie是否存在,并且其值具有根据 - home cooked - generate_my_id()函数的格式 - 然后再次测试$ _SESSION值。但是如果会话过期(没有$ _SESSION ['MyStuff']),则会再次调用非必要的session_start()

所以问题是,基于我的观察,实际上有两个问题

  • 有没有办法在调用session_start()之前指定PHP应该如何创建会话ID(似乎不可能)?

  • 有没有办法检查session_start()是否必须创建新会话,还是只使用一个可用的服务器端? (这将消除其第一次通话)

欢迎任何好的选择。

修改

澄清什么是自定义ID。

会话ID是PHP用于检索服务器上的会话的字符串键,每个用户具有不同的键。该密钥通常存储在cookie中,然后浏览器将该cookie及其请求发送到服务器/ PHP以“连接”到会话。 PHP根据设置,根据MD5(用户和时间相关数据)或SHA1(相同数据)自动设置会话ID密钥。因此,会话ID是MD5或SHA1密钥 - 希望是唯一的。

自定义ID是程序员(我)手动创建的密钥,绕过了md5 / sha1的创建。

2 个答案:

答案 0 :(得分:1)

  1. 是的,从5.3开始,您可以在生成会话ID时使用session.hash_function指定哈希算法;建议不要使用自己的哈希算法,特别是因为散列,速度,冲突等广泛测试哈希算法。

  2. 由于Cookie通常用于使会话永久化,因此您可以使用该信息来确定session_start()是否会创建新会话。

  3. 以下说明了一种最小化所需session_start()语句数量的方法;它是从现有代码(OO)中推导出来的:

    do {
        // discover session by cookie
        if (isset($_COOKIE[session_name()])) {
            session_start();
            // validate session contents
            if (!isset($_SESSION['MyStuff'])) {
                // destroy session and regenerate id
                session_destroy();
                session_regenerate_id(true); // skip this if you generate your own
            } else {
                // validation passed, no need to populate
                break;
            }
        }
        // populate new session
        // you can use session_id($your_id) here
        session_start();
        $_SESSION['MyStuff'] = 'foobar';
    } while (false);
    

    奇怪的do { } while循环只是一个荣耀的goto,因此如果当前会话有效,您可以跳过第二个session_start()

答案 1 :(得分:1)

迟到的答案,但请检查 changelog for PHP v5.5.1

它引用了一个名为SessionIdInterface的新接口,其中只有方法是create_sid,尽管它仍然没有文档。

interface SessionIdInterface  {
    public function create_sid ();
}