我想实现一个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的创建。
答案 0 :(得分:1)
是的,从5.3开始,您可以在生成会话ID时使用session.hash_function
指定哈希算法;建议不要使用自己的哈希算法,特别是因为散列,速度,冲突等广泛测试哈希算法。
由于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()
。
答案 1 :(得分:1)
迟到的答案,但请检查 changelog for PHP v5.5.1
它引用了一个名为SessionIdInterface的新接口,其中只有方法是create_sid,尽管它仍然没有文档。
interface SessionIdInterface {
public function create_sid ();
}