如果使用PHP的默认会话处理,在所有平台上可靠地更改会话持续时间的唯一方法是更改php.ini..这是因为在某些平台中,垃圾收集是通过每隔一段时间运行的脚本实现的(克隆(脚本)直接从php.ini,因此,任何在运行时更改它的尝试,例如ini_set()是不可靠的,而且很可能不起作用。
例如,在DebianLinux系统中,通过设置session.gc_probability=0默认情况下,配置是通过/etc/cron.d/php完成的,它运行在XX:09和XX:39(即每半小时一次)。此cron作业寻找比session.gc_max寿命在配置中指定,如果找到,则删除它们。因此,在这些系统中ini_set('session.gc_maxlifetime', ...)被忽视了。这也解释了为什么在这个问题中:PHP会话超时太快,OP在一个主机上有问题,但切换到另一个主机时问题就停止了。
所以,既然你没有权限php.ini,如果您想可移植地执行此操作,则使用默认会话处理并不是一个选项。显然,延长cookie生存期对主机来说已经足够了,但是如果您想要一个可靠的解决方案,即使您切换了主机,您也必须使用另一个替代方案。
现有的替代方法包括:在PHP中设置不同的会话(保存)处理程序,以将会话保存在不同的目录或数据库中,如PHP:自定义会话处理程序(PHP手册),所以克隆作业没有到达,只有PHP的内部垃圾收集。此选项可能可以利用ini_set()设置session.gc_max寿命但我宁愿忽略最大寿命参数在我的gc()回调并自行确定最大生存期。
完全忘记PHP内部会话处理,并实现您自己的会话管理。此方法有两个主要缺点:您将需要您自己的全局会话变量,因此您将失去$_SESSION超级全局的,它需要更多的代码,因此有更多的漏洞和安全缺陷的机会。最重要的是,会话标识符应该由加密安全的随机或伪随机数字生成,以避免会话ID可预见性(导致可能的会话劫持),这对于PHP来说并不容易。它的主要优点是它将在所有平台上一致工作,并且您可以完全控制代码。这就是我们所采取的方法。phpBB论坛软件(至少第1版;我不确定最近的版本)。
中有一个(1)的示例。文件session_set_save_handler()..这个例子很长,但我将在这里再现它,并对其进行必要的修改,以延长会话持续时间。请注意所包含的session_set_cookie_params()以增加cookie的生存期。<?phpclass FileSessionHandler{
private $savePath;
private $lifetime;
function open($savePath, $sessionName)
{
$this->savePath = 'my_savepath'; // Ignore savepath and use our own to keep it safe from automatic GC
$this->lifetime = 3600; // 1 hour minimum session duration
if (!is_dir($this->savePath)) {
mkdir($this->savePath, 0777);
}
return true;
}
function close()
{
return true;
}
function read($id)
{
return (string)@file_get_contents("$this->savePath/sess_$id");
}
function write($id, $data)
{
return file_put_contents("$this->savePath/sess_$id", $data) === false ? false : true;
}
function destroy($id)
{
$file = "$this->savePath/sess_$id";
if (file_exists($file)) {
unlink($file);
}
return true;
}
function gc($maxlifetime)
{
foreach (glob("$this->savePath/sess_*") as $file) {
if (filemtime($file) + $this->lifetime
unlink($file);
}
}
return true;
}}$handler = new FileSessionHandler();session_set_save_handler(
array($handler, 'open'),
array($handler, 'close'),
array($handler, 'read'),
array($handler, 'write'),
array($handler, 'destroy'),
array($handler, 'gc')
);// the following prevents unexpected effects when using objects as save handlersregister_shutdown_function('session_write_close');
session_set_cookie_params(3600); // Set session cookie duration to 1 hoursession_start();
// proceed to set and retrieve values by key from $_SESSION
方法(2)更复杂;基本上,您必须自己重新实现所有会话功能。我不会在这里详述。