我有一个PHP文件,有时从一个已经开始会话的页面调用,有时从一个没有会话启动的页面调用。因此,当我在这个脚本上有session_start()时,我有时会得到“会话已经开始”的错误消息。为此,我写了以下几行:

if(!isset($_COOKIE["PHPSESSID"]))
{
  session_start();
}

但这次我收到了警告信息:

注意:未定义变量:_SESSION

是否有更好的方法来检查会话是否已经开始?

如果我使用@session_start,它会使事情正常工作,只是关闭警告?


当前回答

session_start();
if(!empty($_SESSION['user']))
{     
  //code;
}
else
{
    header("location:index.php");
}

其他回答

在PHP 5.4之前,除了设置一个全局标志,没有其他可靠的方法。

考虑:

var_dump($_SESSION); // null
session_start();
var_dump($_SESSION); // array
session_destroy();
var_dump($_SESSION); // array, but session isn't active.

Or:

session_id(); // returns empty string
session_start();
session_id(); // returns session hash
session_destroy();
session_id(); // returns empty string, ok, but then
session_id('foo'); // tell php the session id to use
session_id(); // returns 'foo', but no session is active.

因此,在PHP 5.4之前,您应该设置一个全局布尔值。

对于PHP 5.4.0之前的版本:

if(session_id() == '') {
    // session isn't started
}

不过,恕我直言,如果你不知道会话是否已经启动,你真的应该考虑重构会话管理代码……

也就是说,我的观点是主观的,在某些情况下(下面的评论中描述了其中的例子),可能无法知道会话是否已经启动。

基于@Meliza Ramos的回复(见第一个回复)和http://php.net/manual/en/function.phpversion.php,

行动:

如果不存在,定义PHP_VERSION_ID 根据PHP_VERSION_ID定义函数检查版本 定义函数为openSession()安全

只使用openSession()

    // PHP_VERSION_ID is available as of PHP 5.2.7, if our
    // version is lower than that, then emulate it
    if (!defined('PHP_VERSION_ID')) {
        $version = explode('.', PHP_VERSION);

        define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));


        // PHP_VERSION_ID is defined as a number, where the higher the number
        // is, the newer a PHP version is used. It's defined as used in the above
        // expression:
        //
        // $version_id = $major_version * 10000 + $minor_version * 100 + $release_version;
        //
        // Now with PHP_VERSION_ID we can check for features this PHP version
        // may have, this doesn't require to use version_compare() everytime
        // you check if the current PHP version may not support a feature.
        //
        // For example, we may here define the PHP_VERSION_* constants thats
        // not available in versions prior to 5.2.7

        if (PHP_VERSION_ID < 50207) {
            define('PHP_MAJOR_VERSION',   $version[0]);
            define('PHP_MINOR_VERSION',   $version[1]);
            define('PHP_RELEASE_VERSION', $version[2]);

            // and so on, ...
        }
    }

    function phpVersionAtLeast($strVersion = '0.0.0')
    {
        $version = explode('.', $strVersion);

        $questionVer = $version[0] * 10000 + $version[1] * 100 + $version[2];

        if(PHP_VERSION_ID >= $questionVer)
            return true;
        else
            return false;

    }

    function openSession()
    {
        if(phpVersionAtLeast('5.4.0'))
        {
            if(session_status()==PHP_SESSION_NONE)
                session_start();
        }
        else // under 5.4.0
        {
            if(session_id() == '')
                session_start();
        }
    }

使用session_id(),如果没有设置,它将返回一个空字符串。它比检查$_COOKIE更可靠。

if (strlen(session_id()) < 1) {
    session_start();
}

这就是我用来确定会话是否已经开始的方法。使用empty和isset如下所示:

if (empty($_SESSION)  && !isset($_SESSION))  {
    session_start();
}