如何判断会话是否处于活动状态?

根据请求,可以通过几种不同的方法来判断会话是否已经启动,例如:

$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:

  1. 如果任何会话已经启动请求, define('SID')将返回FALSE ,以及$_SESSION未设置。
  2. 无论是否使用session_id()来设置会话ID,这都是独立的。
  3. 在第一个session_start() ,定义了SID并将$_SESSION设置为一个空数组。
  4. session_destroy()没有设置session_id() ,那么它是一个空string。 SID将保持定义(并且设置为之前的值,可能是一个空string)。 $_SESSION保持不变。 它会在下次session_start被调用时被重置/填充。

有了这些状态,尤其是可以调用session_id()来为下一个会话设置id时,不可能安全地使用SID $_SESSIONsession_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。