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
How to tell if a session is active?
提问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 SID
will be defined. Likewise, calling session_start()
at this point will generate an E_NOTICE
if 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 $_SESSION
is not an option for me. For PHP 5.3.8:
我也遇到了这个问题,设置 in$_SESSION
对我来说不是一个选择。对于 PHP 5.3.8:
- If any session has been started with the request,
define('SID')
will returnFALSE
, as well as$_SESSION
is unset. - This is independent whether or not
session_id()
has been used to set a session id or not. - After the first
session_start()
,SID
is defined and$_SESSION
is set to an empty array. session_destroy()
does unset thesession_id()
, it's an empty string then.SID
will remain defined (and set to it's previous value which might be an empty string).$_SESSION
is left unchanged. It will get reset/populated next timesession_start
is called.
- 如果任何会话已通过请求启动,
define('SID')
将返回FALSE
,以及$_SESSION
未设置。 - 这与是否
session_id()
已用于设置会话 ID 无关。 - 在第一个
session_start()
,SID
被定义并$_SESSION
设置为一个空数组之后。 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
, $_SESSION
and 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_handler
when the session is active, not even when you set it to the same value. Same is true for session.use_trans_sid
Docswhich is more lightweight. This lead me to the following function:
在我运行测试时,我遇到了这种行为,即您无法尝试更改session.serialize_handler
会话处于活动状态时的ini 设置,即使将其设置为相同的值也是如此。更轻量级的session.use_trans_sid
Docs也是如此。这导致我使用以下功能:
/**
* @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 数组应该不可用......或者至少,你的值应该是未设置的。因此,理论上(未经测试)您应该能够检查数组中的值以了解当前是否设置了任何值。