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"
编辑8/29/2011:添加到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()。
7 个解决方案
#1
22
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的答案。
#2
15
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.
哈金,但完成了我需要的。
#3
10
I'm running into this as well, and a setting in $_SESSION
is not an option for me. For PHP 5.3.8:
我也遇到了这个问题,$ _SESSION中的设置对我来说不是一个选项。对于PHP 5.3.8:
- If any session has been started with the request,
define('SID')
will returnFALSE
, as well as$_SESSION
is unset. - 如果已经使用请求启动了任何会话,则define('SID')将返回FALSE,并且未设置$ _SESSION。
- This is independent whether or not
session_id()
has been used to set a session id or not. - 无论是否已使用session_id()来设置会话ID,这都是独立的。
- After the first
session_start()
,SID
is defined and$_SESSION
is set to an empty array. - 在第一个session_start()之后,定义了SID并将$ _SESSION设置为空数组。
-
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. - 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 next session, 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.
“尝试”用在session_start()(例如,用@)可能不是真正有用的,因为这将改变会话状态和改变$ _SESSION内容(并添加一个Set-Cookie头如果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
Docs which 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.
一些沙盒。
#4
4
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
#5
1
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);
}
}
#6
0
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.
Ken,如果会话被破坏,$ _SESSION数组应该不可用......或者至少,你的值应该是未设置的。因此,理论上(未经测试)您应该能够检查数组中的值以了解当前是否设置了任何内容。
#7
0
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匹配的记录。
#1
22
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的答案。
#2
15
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.
哈金,但完成了我需要的。
#3
10
I'm running into this as well, and a setting in $_SESSION
is not an option for me. For PHP 5.3.8:
我也遇到了这个问题,$ _SESSION中的设置对我来说不是一个选项。对于PHP 5.3.8:
- If any session has been started with the request,
define('SID')
will returnFALSE
, as well as$_SESSION
is unset. - 如果已经使用请求启动了任何会话,则define('SID')将返回FALSE,并且未设置$ _SESSION。
- This is independent whether or not
session_id()
has been used to set a session id or not. - 无论是否已使用session_id()来设置会话ID,这都是独立的。
- After the first
session_start()
,SID
is defined and$_SESSION
is set to an empty array. - 在第一个session_start()之后,定义了SID并将$ _SESSION设置为空数组。
-
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. - 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 next session, 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.
“尝试”用在session_start()(例如,用@)可能不是真正有用的,因为这将改变会话状态和改变$ _SESSION内容(并添加一个Set-Cookie头如果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
Docs which 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.
一些沙盒。
#4
4
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
#5
1
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);
}
}
#6
0
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.
Ken,如果会话被破坏,$ _SESSION数组应该不可用......或者至少,你的值应该是未设置的。因此,理论上(未经测试)您应该能够检查数组中的值以了解当前是否设置了任何内容。
#7
0
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匹配的记录。