2

我想实现一个 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 是否存在,其值是否具有根据 - homecooked - generate_my_id() 函数的格式 - 然后再次测试 $_SESSION 值是否存在。但是,如果会话过期(没有 $_SESSION['MyStuff']),session_start()将再次调用不必要的会话。

所以问题是,根据我的观察,实际上是两个问题

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

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

欢迎任何好的选择。

编辑

澄清什么是自定义 ID。

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

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

4

2 回答 2

1

迟到的答案,但请检查PHP v5.5.1的更改日志

它引用了一个名为 SessionIdInterface 的新接口,该接口唯一的方法是 create_sid,尽管它仍然没有记录。

interface SessionIdInterface  {
    public function create_sid ();
}
于 2014-01-03T18:56:01.390 回答
1
  1. session.hash_function是的,从 5.3 开始,您可以在生成会话 ID 时指定哈希算法;不建议使用您自己的哈希算法,特别是因为哈希附带的算法已经过广泛的传播、速度、冲突等测试。

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

下面说明了一种最小化所需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()

于 2012-10-16T08:39:36.243 回答