如何在PHP中更改会话超时?

我想在PHP中延长会话超时

我知道可以通过修改php.ini文件来做到这一点。 但我没有访问它。

那么是否有可能只使用PHP代码?

会话超时是一个概念,必须在代码中实现,如果你想严格保证; 这是唯一的方法,你可以绝对肯定,没有任何会议将经过X分钟的不活动后生存。

如果放宽这个要求是可以接受的,你可以放置一个下限而不是严格限制持续时间,你可以很容易地做,而不需要编写自定义逻辑。

在轻松的环境中方便:如何和为什么

如果您的会话是通过cookie(他们可能是)来实现的,并且如果客户端不是恶意的,您可以通过调整某些参数来设置会话持续时间的上限。 如果您正在使用PHP的默认会话处理cookie,则设置session.gc_maxlifetime以及session_set_cookie_params应该适合您:

 // server should keep session data for AT LEAST 1 hour ini_set('session.gc_maxlifetime', 3600); // each client should remember their session id for EXACTLY 1 hour session_set_cookie_params(3600); session_start(); // ready to go! 

这可以通过configuration服务器使会话数据保持至less一小时不活动状态,并指示客户在同一时间段后应该“忘记”会话ID。 这两个步骤都需要达到预期的结果。

  • 如果您不告诉客户在一小时后忘记会话ID(或者如果客户端是恶意的并且select忽略您的指示),他们将继续使用相同的会话ID,并且其有效持续时间将是不确定的。 这是因为在服务器端生命周期已到期的会话不会立即垃圾回收,而只会在会话GC启动时发生 。

    GC是一个潜在的昂贵的过程,所以一般情况下这个概率很小,甚至为零(一个网站获得大量的点击可能完全放弃概率GC,并计划每隔X分钟在后台进行)。 在这两种情况下(假设不合作的客户端)有效会话生存时间的下限将是session.gc_maxlifetime ,但是上限将是不可预测的。

  • 如果您没有将session.gc_maxlifetime设置为相同的时间范围,那么服务器可能会在此之前丢弃闲置的会话数据; 在这种情况下,仍然记住其会话ID的客户机将显示它,但服务器将找不到与该会话关联的任何数据,有效地performance为会话刚刚开始。

在关键环境中的确定性

你可以通过使用自定义逻辑来使事情完全可控,以便在会话不活动时放置一个上限 ; 再加上上面的下限就会导致严格的设定。

通过与会话数据的其余部分一起保存上限来做到这一点:

 session_start(); // ready to go! $now = time(); if (isset($_SESSION['discard_after']) && $now > $_SESSION['discard_after']) { // this session has worn out its welcome; kill it and start a brand new one session_unset(); session_destroy(); session_start(); } // either new or old, it should live at most for another hour $_SESSION['discard_after'] = $now + 3600; 

会话ID持久性

到目前为止,我们一直没有关心每个会话id的确切值,只是要求数据应该存在,只要我们需要它们。 请注意,在会话对您来说很重要的(不太可能)的情况下,必要时必须小心使用session_regenerate_id重新生成它们。

如果您使用PHP的默认会话处理,可靠地更改所有平台的会话持续时间的唯一方法是更改php.ini 。 这是因为在某些平台上,垃圾收集是通过一个脚本来实现的,该脚本每隔一段时间( cron脚本)运行,直接从php.ini读取,因此任何尝试在运行时更改它(例如通过ini_set()是不可靠的而且很可能不会工作。

例如,在Debian Linux系统中,垃圾回收是通过/etc/cron.d/php5完成的,它在XX:09和XX:39(即每半个小时)运行一次,如果发现会话比会话早在php.ini中指定.gc_maxlifetime ,那么该会话将被删除。 这也解释了为什么在这个问题中: PHP会话超时太快 ,OP在一台主机上出现问题,但切换到不同的主机时问题停止了。

所以,鉴于你没有访问php.ini ,如果你想要移植它,使用默认的会话处理不是一个选项。 显然,延长cookie的生命周期对于你的主机来说已经足够了,但是如果你想要一个即使切换主机也能可靠工作的解决scheme,你必须使用另一种方法。

可用的替代方法包括:

  1. 在PHP中设置一个不同的会话(保存)处理程序,以将会话保存在不同的目录或数据库中,如PHP:自定义会话处理程序(PHP手册)中所述 ,以便cron作业无法达到此目的,只有PHP内部垃圾收集发生。 这个选项可能会使用ini_set()来设置session.gc_maxlifetime,但我更喜欢忽略我的gc()callback函数中的maxlifetime参数,并确定最大的生命周期。

  2. 完全忘记PHP内部会话处理并实现您自己的会话pipe理。 这种方法有两个主要的缺点:你将需要你自己的全局会话variables,所以你失去了$_SESSION超全球的优势,它需要更多的代码,因此有更多的错误和安全漏洞的机会。 最重要的是,会话标识符应该由密码安全的随机或伪随机数生成,以避免会话ID的可预测性(导致可能的会话劫持),这对于PHP来说并不容易。 主要优点是它可以在所有平台上一致地工作,并且完全控制代码。 这是由phpBB论坛软件采取的方法(至less版本1;我不确定更新的版本)。

session_set_save_handler()的文档中有一个(1)的例子。 这个例子很长,但我会在这里复制它,并且需要进行相应的修改来延长会话持续时间。 注意包含session_set_cookie_params()以增加cookie的生命周期。

 <?php class 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 < time() && file_exists($file)) { // Use our own 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 handlers register_shutdown_function('session_write_close'); session_set_cookie_params(3600); // Set session cookie duration to 1 hour session_start(); // proceed to set and retrieve values by key from $_SESSION 

方法(2)更复杂; 基本上,你必须自己重新实现所有的会话function。 我不会在这里详述。

不可以。如果您无法访问php.ini,则无法保证更改会有任何影响。

我怀疑你需要延长会议时间。
目前暂停的时间非常明显,没有理由延长。

您可以使用ini_set()从您的PHP代码覆盖php.ini中的值。

$_SESSION['login_time'] = time(); 进入之前的authentication页面。 然后在其他所有要查看会话超时的页面中查看。

 if(time() - $_SESSION['login_time'] >= 1800){ header("Location: logout.php"); //redirect if the page is inactive for 30 minutes } else { $_SESSION['login_time'] = time(); // update value of session }