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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3788369/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 11:07:17  来源:igfitidea点击:

How to tell if a session is active?

phpsession

提问by ken

Per request, there are a few different ways that you can tell whether or not a session has been started, such as:

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

$isSessionActive = (session_id() != "");

Or:

或者:

$isSessionActive = defined('SID');

However, these both fail if you start a session, then close it; session_id()will return the prior session's ID, while SIDwill be defined. Likewise, calling session_start()at this point will generate an E_NOTICEif you already have a session active. Is there a sane way to check if a session is currently active, without having to resort to output buffering, the shut-up operator (@session_start()), or something else equally as hacky?

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

EDIT: I wrote a patch to try to get this functionality included in PHP: http://bugs.php.net/bug.php?id=52982

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

EDIT 8/29/2011: New function added to PHP 5.4 to fix this: "Expose session status via new function, session_status"

2011 年 8 月 29 日编辑:PHP 5.4 中添加了新函数以解决此问题:“通过新函数 session_status 公开会话状态”

// as of 8/29/2011
$isSessionActive = (session_status() == PHP_SESSION_ACTIVE);

EDIT 12/5/11: session_status()on the PHP manual.

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

采纳答案by ken

See edits to the original question; basically, PHP 5.4 and above now has a function called session_status()to solve this problem!

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

"Expose session status via new function, session_status" (SVN Revision 315745)

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

If you need this functionality in a pre-PHP 5.4 version, see hakre's answer.

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

回答by Marc B

I worked around this by adding a couple wrapper functions around the various session creation/closing/destroying functions. Basically:

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

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']);
}

Hackish, but accomplished what I needed.

Hackish,但完成了我需要的。

回答by hakre

I'm running into this as well, and a setting in $_SESSIONis not an option for me. For PHP 5.3.8:

我也遇到了这个问题,设置 in$_SESSION对我来说不是一个选择。对于 PHP 5.3.8:

  1. If any session has been started with the request, define('SID')will return FALSE, as well as $_SESSIONis unset.
  2. This is independent whether or not session_id()has been used to set a session id or not.
  3. After the first session_start(), SIDis defined and $_SESSIONis set to an empty array.
  4. session_destroy()does unset the session_id(), it's an empty string then. SIDwill remain defined (and set to it's previous value which might be an empty string). $_SESSIONis left unchanged. It will get reset/populated next time session_startis called.
  1. 如果任何会话已通过请求启动,define('SID')将返回FALSE,以及$_SESSION未设置。
  2. 这与是否session_id()已用于设置会话 ID 无关。
  3. 在第一个session_start(),SID被定义并$_SESSION设置为一个空数组之后。
  4. session_destroy()确实取消了session_id(),然后它是一个空字符串。SID将保持定义(并设置为它的先前值,可能是一个空字符串)。$_SESSION保持不变。下次session_start调用时它将被重置/填充。

With these states, especially as session_id()can be called in between to set the id for the nextsession, it's not possible to safely determine the session status with SID, $_SESSIONand session_id().

对于这些状态,尤其是session_id()可以在它们之间调用以设置下一个会话的 id 时,不可能使用SID,$_SESSION和安全地确定会话状态session_id()

"Trying" with session_start()(e.g. with @) might not be really helpful, as this will change the session status and changing the contents of $_SESSION(and adding a set-cookie header if the cookie was not part of the request). It was not fitting in my case.

“尝试” with session_start()(例如 with @)可能不是很有帮助,因为这将更改会话状态并更改其内容$_SESSION(如果 cookie 不是请求的一部分,则添加 set-cookie 标头)。它不适合我的情况。

While I was running tests, I came across the behaviour, that you can not try to change the ini setting of session.serialize_handlerwhen the session is active, not even when you set it to the same value. Same is true for session.use_trans_sidDocswhich is more lightweight. This lead me to the following function:

在我运行测试时,我遇到了这种行为,即您无法尝试更改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;
}

As far as I can see, the error is checking for active session status only (not disabled), so this should not return a false positive when sessions are disabled.

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

To get this function compatible with PHP 5.2, it needs a little modification:

为了让这个函数兼容 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;
}

Some sandbox.

一些沙箱

回答by Robert

The following code only dumps one session_id() for me, not two

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

session_start();
echo session_id();
session_destroy();
echo session_id();

If you're having difficulties with this still you can try creating a variable to check, that you destroy when you destroy the session.

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

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

回答by Beachhouse

Here's a good drop in replacement that won't break stuff when you move to 5.4:

这是一个很好的替代品,当你移动到 5.4 时不会破坏东西:

if(!function_exists('session_status')){
    function session_active(){
        return defined('SID');   
    }
}else{
    function session_active(){
        return (session_status() == PHP_SESSION_ACTIVE);   
    }        
}

回答by beiller

There are multiple places you need to check to verify the session is active:

您需要检查多个位置以验证会话是否处于活动状态:

1- cookie exists and is not expired 2- underlying session storage mechanism (file system or database) has a record matching the cookie.

1- cookie 存在且未过期 2- 底层会话存储机制(文件系统或数据库)具有与 cookie 匹配的记录。

回答by bpeterson76

Ken, if the session is destroyed, the $_SESSION array should not be available...or at the very least, your values should be unset. So, in theory (untested) you should be able to check the array for a value to know if anything is currently set.

肯,如果会话被破坏, $_SESSION 数组应该不可用......或者至少,你的值应该是未设置的。因此,理论上(未经测试)您应该能够检查数组中的值以了解当前是否设置了任何值。