如何判断会话是否有效?

ken*_*ken 41 php session

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

$isSessionActive = (session_id() != "");
Run Code Online (Sandbox Code Playgroud)

要么:

$isSessionActive = defined('SID');
Run Code Online (Sandbox Code Playgroud)

但是,如果你开始一个会话,然后关闭它们,它们都会失败; session_id()将返回先前会话的ID,同时SID将定义.同样,如果您已经激活会话,此时调用session_start()将生成一个E_NOTICE.是否有一种理智的方法来检查会话当前是否处于活动状态,而不必求助于输出缓冲,关闭运算符(@session_start())或其他类似hacky的东西?

编辑:我写了一个补丁试图让这个功能包含在PHP中:http://bugs.php.net/bug.php?id = 52982

编辑8/29/2011:添加到PHP 5.4的新功能修复此问题:"通过新函数,session_status公开会话状态"

// as of 8/29/2011
$isSessionActive = (session_status() == PHP_SESSION_ACTIVE);
Run Code Online (Sandbox Code Playgroud)

编辑12/5/11:PHP手册上的session_status().

ken*_*ken 22

查看原始问题的编辑; 基本上,PHP 5.4及以上版本现在有一个函数session_status()来解决这个问题!

"通过新函数session_status公开会话状态"(SVN修订版315745)

如果您在PHP 5.4之前的版本中需要此功能,请参阅hakre的答案.


Mar*_*c B 15

我通过在各种会话创建/关闭/销毁功能周围添加几个包装函数来解决这个问题.基本上:

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']);
}
Run Code Online (Sandbox Code Playgroud)

哈希,但完成了我所需要的.


hak*_*kre 10

我也遇到了这种情况,并且$_SESSION我不能选择设置.对于PHP 5.3.8:

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

有了这些状态,特别是session_id()可以在两者之间调用以设置下一个会话的id ,就不可能用SID,$_SESSION和安全地确定会话状态session_id().

使用session_start()(例如with @)"尝试" 可能不太有用,因为这会改变会话状态并更改内容$_SESSION(如果cookie不是请求的一部分,则添加set-cookie头).这不适合我的情况.

在我运行测试时,我遇到了这样的行为,即您无法尝试更改session.serialize_handler会话处于活动状态时的ini设置,即使您将其设置为相同的值也是如此.对于更轻量级的session.use_trans_sidDocs也是如此.这引出了以下功能:

/**
 * @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;
}
Run Code Online (Sandbox Code Playgroud)

据我所知,错误是仅检查活动会话状态(未禁用),因此在禁用会话时不应返回误报.

要使此功能与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;
}
Run Code Online (Sandbox Code Playgroud)

一些沙盒.


Rob*_*ert 5

以下代码只为我转储了一个session_id(),而不是两个

session_start();
echo session_id();
session_destroy();
echo session_id();
Run Code Online (Sandbox Code Playgroud)

如果您对此仍然有困难,可以尝试创建一个变量来检查,以便在销毁会话时销毁该变量。

session_start();
$_SESSION['intialized'] = 'This will not print';
$_SESSION = array(); // Unset all variables
session_destroy();
echo $_SESSION['initialized']; // No output
Run Code Online (Sandbox Code Playgroud)

  • 但是,如果您使用session_write_close(),则会话已关闭,但是$ _SESSION数据仍然存在,这就是我认为OP正在使用的...您如何检查会话文件本身是否仍在使用中? (3认同)