PHP 会话将在 40 分钟后过期
PHP session expiring after 40 minutes
我编写了这段代码来管理会话,以便它们在浏览器关闭或用户在定义的时间(2 小时)内不活动时过期。然而,会话似乎在 40 分钟不活动后到期,我真的不明白这怎么可能。如果我的代码失败,我希望它们应该持续 1440 秒(24 分钟)。
define("MY_SESSION", "mysession");
define("SESSION_DURATION", 7200);
function my_session_start() {
if (session_status() != PHP_SESSION_NONE)
return;
ini_set('session.gc_maxlifetime', SESSION_DURATION);
ini_set('session.cookie_lifetime', 0);
session_set_cookie_params(0);
session_name(MY_SESSION);
session_start();
if ((!isset($_SESSION['EXPIRES'])) || ($_SESSION['EXPIRES'] < time())) {
$_SESSION = array();
session_unset();
session_destroy();
session_start();
}
$_SESSION['EXPIRES'] = time() + SESSION_DURATION;
if (isset($_SESSION['REGENERATE'])) {
$_SESSION['REGENERATE']++;
if ($_SESSION['REGENERATE'] >= mt_rand(90,100)) {
$_SESSION['REGENERATE'] = 0;
session_regenerate_id(true);
}
}
else {
$_SESSION['REGENERATE'] = 0;
session_regenerate_id(true);
}
}
我在每个 PHP 文件中放置了 my_session_start()
。
我在共享服务器上,但 ini_set()
未被阻止,通过在 my_session_start()
之后启动 phpinfo()
我可以看到 session.gc_maxlifetime
本地值被设置为 7200(而主值为 1440)。 session.gc_probability
和 session.gc_divisor
保留其默认值(分别为 1 和 100)。
我还在 90-100 页面加载/AJAX 调用的随机基础上重新生成会话 ID,但这并不重要,因为我也尝试注释掉那部分但它没有解决问题。
所以,我的代码有问题吗?那分钟数是从哪里来的,我的意思是为什么是 40 分钟?
所以我终于想出了解决这个问题的方法。
解决方案是更改会话文件保存文件夹:
ini_set('session.save_path', "/the/new/path/to/sessions/"); //DEFAULT: /var/lib/php5
这样做意味着可能会查看会话文件,因此我添加了包含以下内容的 .htaccess 文件:
deny from all
在“/the/new/path/to/sessions/”文件夹中。所以服务器外什么也看不到。
此外,我必须添加一个新的会话垃圾收集功能:
function clear_old_sessions() {
$folder = "/the/new/path/to/sessions/";
$files = scandir($folder);
for ($i = 0; $i < count($files); $i++) {
$file = $folder . $files[$i];
if (is_file($file))
if (substr($files[$i], 0, 5) == "sess_")
if ((filemtime($file) + SESSION_DURATION) < time()) // SESSION_DURATION previosuly defined as 7200 (seconds)
unlink($file);
}
}
我编写了这段代码来管理会话,以便它们在浏览器关闭或用户在定义的时间(2 小时)内不活动时过期。然而,会话似乎在 40 分钟不活动后到期,我真的不明白这怎么可能。如果我的代码失败,我希望它们应该持续 1440 秒(24 分钟)。
define("MY_SESSION", "mysession");
define("SESSION_DURATION", 7200);
function my_session_start() {
if (session_status() != PHP_SESSION_NONE)
return;
ini_set('session.gc_maxlifetime', SESSION_DURATION);
ini_set('session.cookie_lifetime', 0);
session_set_cookie_params(0);
session_name(MY_SESSION);
session_start();
if ((!isset($_SESSION['EXPIRES'])) || ($_SESSION['EXPIRES'] < time())) {
$_SESSION = array();
session_unset();
session_destroy();
session_start();
}
$_SESSION['EXPIRES'] = time() + SESSION_DURATION;
if (isset($_SESSION['REGENERATE'])) {
$_SESSION['REGENERATE']++;
if ($_SESSION['REGENERATE'] >= mt_rand(90,100)) {
$_SESSION['REGENERATE'] = 0;
session_regenerate_id(true);
}
}
else {
$_SESSION['REGENERATE'] = 0;
session_regenerate_id(true);
}
}
我在每个 PHP 文件中放置了 my_session_start()
。
我在共享服务器上,但 ini_set()
未被阻止,通过在 my_session_start()
之后启动 phpinfo()
我可以看到 session.gc_maxlifetime
本地值被设置为 7200(而主值为 1440)。 session.gc_probability
和 session.gc_divisor
保留其默认值(分别为 1 和 100)。
我还在 90-100 页面加载/AJAX 调用的随机基础上重新生成会话 ID,但这并不重要,因为我也尝试注释掉那部分但它没有解决问题。
所以,我的代码有问题吗?那分钟数是从哪里来的,我的意思是为什么是 40 分钟?
所以我终于想出了解决这个问题的方法。 解决方案是更改会话文件保存文件夹:
ini_set('session.save_path', "/the/new/path/to/sessions/"); //DEFAULT: /var/lib/php5
这样做意味着可能会查看会话文件,因此我添加了包含以下内容的 .htaccess 文件:
deny from all
在“/the/new/path/to/sessions/”文件夹中。所以服务器外什么也看不到。
此外,我必须添加一个新的会话垃圾收集功能:
function clear_old_sessions() {
$folder = "/the/new/path/to/sessions/";
$files = scandir($folder);
for ($i = 0; $i < count($files); $i++) {
$file = $folder . $files[$i];
if (is_file($file))
if (substr($files[$i], 0, 5) == "sess_")
if ((filemtime($file) + SESSION_DURATION) < time()) // SESSION_DURATION previosuly defined as 7200 (seconds)
unlink($file);
}
}