Oli*_*Oli 142 php session session-timeout
我想在php中扩展会话超时
我知道可以通过修改php.ini文件来实现.但我无法访问它.
那么有可能只用PHP代码吗?
Jon*_*Jon 302
会话超时是一个必须在代码中实现的概念,如果您需要严格保证; 这是你绝对可以确定在X分钟不活动后没有会话能够存活的唯一方法.
如果放宽这个要求有一点是可以接受的,你可以放置一个下限而不是严格的持续时间限制,你可以轻松地这样做,而无需编写自定义逻辑.
如果您的会话与饼干(他们可能是)来实现,并且如果客户端是没有恶意的,你可以通过调整某些参数设置会话持续时间的上限.如果您使用的是带有饼干PHP的默认会话处理,设置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!
Run Code Online (Sandbox Code Playgroud)
这可以通过配置服务器来保持会话数据至少一小时不活动,并指示您的客户在相同的时间跨度后"忘记"他们的会话ID.需要这两个步骤才能达到预期的效果.
如果您没有告诉客户在一小时后忘记他们的会话ID(或者如果客户端是恶意的并且选择忽略您的指示),他们将继续使用相同的会话ID,并且其有效持续时间将是不确定的.这是因为服务器端的生命周期已到期的会话不会立即被垃圾收集,而是仅在会话GC启动时.
GC是一个潜在的昂贵过程,因此通常概率相当小甚至为零(网站获得大量点击可能会完全放弃概率GC并安排它每隔X分钟在后台进行一次).在这两种情况下(假设非合作客户端),有效会话生存期的下限将是session.gc_maxlifetime,但上限将是不可预测的.
如果未设置session.gc_maxlifetime为相同的时间跨度,则服务器可能会在此之前丢弃空闲会话数据; 在这种情况下,仍然会记住其会话ID的客户端将显示它,但服务器将找不到与该会话相关联的数据,实际上就像会话刚刚启动一样.
您可以通过使用自定义逻辑使事件完全可控,也可以在会话不活动时设置上限 ; 与上面的下限一起,这导致严格的设置.
通过将上限与其余会话数据一起保存来执行此操作:
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;
Run Code Online (Sandbox Code Playgroud)
到目前为止,我们并没有完全关注每个会话id的确切值,只要要求数据应该存在,只要我们需要它们.请注意,在(不太可能)会话ID对您很重要的情况下,必须注意session_regenerate_id在需要时重新生成它们.
Ped*_*eno 32
如果您使用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的生命周期对于您的主机来说已经足够了,但如果您想要一个即使切换主机也能可靠运行的解决方案,您必须使用不同的替代方案.
可用的替代方法包括:
在PHP中设置一个不同的会话(保存)处理程序,将会话保存在不同的目录或数据库中,如PHP中所指定的:自定义会话处理程序(PHP手册),以便cron作业无法访问它,只有PHP的内部垃圾收集发生.这个选项可能可以session.gc_probability=0用来设置session.gc_maxlifetime,但我更喜欢忽略回调中的maxlifetime参数,ini_set('session.gc_maxlifetime', ...)并自己确定最大生命周期.
完全忘记PHP内部会话处理并实现自己的会话管理.这种方法有两个主要缺点:您需要自己的全局会话变量,因此您将失去ini_set()超全局的优势,并且需要更多代码,因此存在更多错误和安全漏洞的机会.最重要的是,会话标识符应该使用加密安全的随机或伪随机数生成,以避免会话ID可预测性(导致可能的会话劫持),并且这对于移植PHP来说并不容易.它的主要优点是它可以在所有平台上一致地工作,并且您可以完全控制代码.这是采用例如phpBB论坛软件(至少版本1;我不确定更新版本)的方法.
文档中gc()有一个(1)的例子.这个例子很长,但我会在这里重现它,并进行必要的相关修改以延长会话持续时间.请注意包含$_SESSION以增加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
Run Code Online (Sandbox Code Playgroud)
方法(2)更复杂; 基本上,您必须自己重新实现所有会话功能.我不会在这里详述.
小智 13
只是共享托管服务器或添加到域的通知=
为了使您的设置生效,您必须使用不同的保存会话目录来添加域php_value session.save_path folderA/sessionsA。
因此,创建一个文件夹到您的根服务器,而不是进入public_html并且不被从外部公开访问。对于我的 cpanel/服务器,文件夹权限工作正常0700。试一下...
# Session timeout, 2628000 sec = 1 month, 604800 = 1 week, 57600 = 16 hours, 86400 = 1 day
ini_set('session.save_path', '/home/server/.folderA_sessionsA');
ini_set('session.gc_maxlifetime', 57600);
ini_set('session.cookie_lifetime', 57600);
# session.cache_expire is in minutes unlike the other settings above
ini_set('session.cache_expire', 960);
ini_set('session.name', 'MyDomainA');
Run Code Online (Sandbox Code Playgroud)
前session_start();
或将其放入您的.htaccess文件中。
php_value session.save_path /home/server/.folderA_sessionsA
php_value session.gc_maxlifetime 57600
php_value session.cookie_lifetime 57600
php_value session.cache_expire 57600
php_value session.name MyDomainA
Run Code Online (Sandbox Code Playgroud)
经过多次研究和测试,这对于共享 cpanel/php7 服务器来说效果很好。非常感谢:NoiS
| 归档时间: |
|
| 查看次数: |
287359 次 |
| 最近记录: |