如何判断会话是否处于活动状态?
根据请求,可以通过几种不同的方法来判断会话是否已经启动,例如:
$isSessionActive = (session_id() != "");
要么:
$isSessionActive = defined('SID');
但是,如果你开始一个会话,这些都会失败,然后closures它; session_id()
将返回先前会话的ID,而SID
将被定义。 同样,如果您已经有一个会话激活,那么在这个时候调用session_start()
将会生成一个E_NOTICE
。 有没有一个理智的方法来检查一个会话当前是否处于活动状态,而不必诉诸于输出缓冲,closures操作符( @session_start()
)或其他同样的操作?
编辑:我写了一个补丁,试图得到这个function包括在PHP中: http : //bugs.php.net/bug.php?id=52982
编辑8/29/2011:新function添加到PHP 5.4来解决这个问题: “通过新function,session_status公开会话状态”
// as of 8/29/2011 $isSessionActive = (session_status() == PHP_SESSION_ACTIVE);
编辑12/5/11:在PHP手册上的session_status() 。
查看原始问题的编辑; 基本上,PHP 5.4及以上版本现在有一个函数叫做session_status()
来解决这个问题!
“通过新函数session_status公开会话状态”(SVN修订版315745)
如果您需要使用PHP 5.4以前的版本,请参阅hakre的答案 。
我通过在各种会话创build/closures/销毁function周围添加了一些包装函数来解决这个问题。 基本上:
function open_session() { session_start(); $_SESSION['is_open'] = TRUE; } function close_session() { session_write_close(); $_SESSION['is_open'] = FALSE; } function destroy_session() { session_destroy(); $_SESSION['is_open'] = FALSE; } function session_is_open() { return($_SESSION['is_open']); }
黑客,但完成了我所需要的。
我也遇到了这个问题, $_SESSION
的设置不适合我。 对于PHP 5.3.8:
- 如果任何会话已经启动请求,
define('SID')
将返回FALSE
,以及$_SESSION
未设置。 - 无论是否使用
session_id()
来设置会话ID,这都是独立的。 - 在第一个
session_start()
,定义了SID
并将$_SESSION
设置为一个空数组。 -
session_destroy()
没有设置session_id()
,那么它是一个空string。SID
将保持定义(并且设置为之前的值,可能是一个空string)。$_SESSION
保持不变。 它会在下次session_start
被调用时被重置/填充。
有了这些状态,尤其是可以调用session_id()
来为下一个会话设置id时,不可能安全地使用SID
$_SESSION
和session_id()
来确定会话状态。
使用session_start()
(例如使用@
)“尝试”可能不是真正有用的,因为这会改变会话状态并更改$_SESSION
的内容(并且如果cookie不是请求的一部分,则添加set-cookie标头) 。 这不适合我的情况。
当我正在运行testing时,我遇到了这样的行为,当会话处于活动状态时,不能尝试更改session.serialize_handler
的ini设置,即使将其设置为相同的值也不行。 session.use_trans_sid
同样适用于更轻量级的文档 。 这导致我以下function:
/** * @return bool */ function session_is_active() { $setting = 'session.use_trans_sid'; $current = ini_get($setting); if (FALSE === $current) { throw new UnexpectedValueException(sprintf('Setting %s does not exists.', $setting)); } $result = @ini_set($setting, $current); return $result !== $current; }
据我所知,错误是只检查活动会话状态(不禁用),所以这不应该返回一个误报,当会话被禁用。
为了使这个function与PHP 5.2兼容,需要稍加修改:
/** * @return bool */ function session_is_active() { $setting = 'session.use_trans_sid'; $current = ini_get($setting); if (FALSE === $current) { throw new UnexpectedValueException(sprintf('Setting %s does not exists.', $setting)); } $testate = "mix$current$current"; $old = @ini_set($setting, $testate); $peek = @ini_set($setting, $current); $result = $peek === $current || $peek === FALSE; return $result; }
一些沙箱 。
以下代码仅为我转储一个session_id(),而不是两个
session_start(); echo session_id(); session_destroy(); echo session_id();
如果你仍然有这个问题,你可以尝试创build一个variables来检查,当你破坏会话的时候你会破坏它。
session_start(); $_SESSION['intialized'] = 'This will not print'; $_SESSION = array(); // Unset all variables session_destroy(); echo $_SESSION['initialized']; // No output
这是一个很好的下降替代,当你移动到5.4时不会破坏东西:
if(!function_exists('session_status')){ function session_active(){ return defined('SID'); } }else{ function session_active(){ return (session_status() == PHP_SESSION_ACTIVE); } }
肯,如果会话被销毁,$ _SESSION数组应该不可用…或者至less,您的值应该是未设置的。 所以,在理论上(未经testing),您应该能够检查数组中是否有值,以了解当前是否设置了任何值。
有多个地方需要检查以确认会话处于活动状态:
1-存在cookie并且不过期2-基础会话存储机制(文件系统或数据库)具有与cookie匹配的logging。