PHP 7.2 警告:“会话处于活动状态时无法更改会话名称”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47700336/
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-26 02:35:16  来源:igfitidea点击:

PHP 7.2 Warning: "Cannot change session name when session is active"

phpsessioncookiesphp-7.2

提问by Blackbam

Since PHP on our server was upgraded to 7.2 from 7.0. I am getting the following warning (which leads to error) if a new deployment is done. The reason is probably, that old sessions get invalid after deployment.

由于我们服务器上的 PHP 从 7.0 升级到 7.2。如果新部署完成,我会收到以下警告(这会导致错误)。原因可能是,旧会话在部署后无效。

Warning: session_name(): Cannot change session name when session is active in/var/www/html/model/login/lib/Session.class.php on line 137

Warning: session_set_cookie_params(): Cannot change session cookie parameters when session is active in/var/www/html/model/login/lib/Session.class.php on line 138

Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/model/login/lib/Session.class.php:137) in /var/www/html/model/login/lib/Session.class.php on line 142

警告:session_name():第 137 行的 /var/www/html/model/login/lib/Session.class.php 中的会话处于活动状态时,无法更改会话名称

警告:session_set_cookie_params():第 138 行的 /var/www/html/model/login/lib/Session.class.php 中的会话处于活动状态时,无法更改会话 cookie 参数

警告:无法修改标头信息 - 标头已由 /var/www/html/model/login/lib/ 中的(输出开始于 /var/www/html/model/login/lib/Session.class.php:137)发送第 142 行的 Session.class.php

It seems like PHP 7.2 got more strict in the context of session sin a certain context. The server seems to recognize the invalid sessions and tries to destroy those. This is part of the Session class:

似乎 PHP 7.2 在 session sin 的上下文中变得更加严格。服务器似乎识别出无效会话并尝试销毁它们。这是 Session 类的一部分:

/**
 * Secure instant destruction of session. Must be called after session_start !
 */
public static function destroyAbsolute() {

    self::checkInit(); // unimportant

    session_name(self::$name); // this is line 137
    session_set_cookie_params(0, COOKIEPATH, null, self::$force_ssl_cookie, true);

    if(session_id()) {
        if (isset($_COOKIE[session_name()])) {
            setcookie(session_name(), "", time() - 42000, COOKIEPATH);
        }
        unset($_COOKIE[session_name()]);
        session_destroy();
    }
}

What has changed in PHP regarding sessions?

PHP 在会话方面发生了哪些变化?

Why is it not allowed to set a session name if another session is active (according to the docs with session_name I could change sessions and start multiple sessions)?

如果另一个会话处于活动状态,为什么不允许设置会话名称(根据 session_name 的文档,我可以更改会话并启动多个会话)?

And how may I destroy the running session appropriately?

以及如何适当地销毁正在运行的会话?

Doing further research I also have found the following discussion on GitHub (https://github.com/Icinga/icingaweb2/issues/3185). They confirm that this error was introduced with PHP 7.2. Unfortunatly there is also no answer :-/

做进一步的研究,我还在 GitHub ( https://github.com/Icinga/icingaweb2/issues/3185)上找到了以下讨论。他们确认这个错误是在 PHP 7.2 中引入的。不幸的是,也没有答案:-/

采纳答案by Blackbam

I have done a bug report at php.net and they explained that this is not a bug. Yes in PHP 7.2 a warning is generated now.However this never worked as intended, it just failed silently.

我在 php.net 上做了一个错误报告,他们解释说这不是一个错误。是的,在 PHP 7.2 中现在会生成警告。然而,这从未按预期工作,它只是默默地失败了

For creating multiple sessions it is required to use session_id(). Have a look at this related question: PHP How can I create multiple sessions?

要创建多个会话,需要使用session_id(). 看看这个相关的问题:PHP 如何创建多个会话?

session_name()as well as session_set_cookie_params()are always nonesense if the session is already running.

session_name()以及session_set_cookie_params()总是nonesense如果会话已在运行。

For the original answer have a look here: https://bugs.php.net/bug.php?id=75650&thanks=2

对于原始答案,请看这里:https: //bugs.php.net/bug.php?id=75650&thanks=2

回答by Miracool

I had a similar problem but finally found a way through. The code below was my first approach that gave me errors.

我有一个类似的问题,但终于找到了解决办法。下面的代码是我第一个给我错误的方法。

static function startmysession($lifetime, $path, $domain, $secure, $httponly){

    session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly);
    session_regenerate_id(true);

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

Now Earlier versions of php overlooked our mistake(We were practically renaming and giving a session that already exists properties which is very wrong. So how did i solve this problem?

现在早期版本的 php 忽略了我们的错误(我们实际上是在重命名并给出一个已经存在的属性的会话,这是非常错误的。那么我是如何解决这个问题的呢?

static function startmysession($lifetime, $path, $domain, $secure, $httponly){      
    if(!isset($_SESSION)){  
         session_set_cookie_params($lifetime, $path, $domain, $secure, $httponly);
         @session_regenerate_id(true);    
             session_start();
         }    
    }

I now bound the session_set_cookie_params()just before session start and I test if the session already exists before doing so.

我现在session_set_cookie_params()在会话开始之前绑定了会话,并在这样做之前测试会话是否已经存在。

回答by Jayen

TLDR:if the session exists, use setcookie(session_name(), session_id(), ...)else use session_set_cookie_params(...)

TLDR:如果会话存在,则使用setcookie(session_name(), session_id(), ...)else usesession_set_cookie_params(...)

https://www.php.net/manual/en/function.session-set-cookie-params.php#100657

https://www.php.net/manual/en/function.session-set-cookie-params.php#100657

As PHP's Session Control does not handle session lifetimes correctly when using session_set_cookie_params(), we need to do something in order to change the session expiry time every time the user visits our site. So, here's the problem.

<?php
  $lifetime=600;
  session_set_cookie_params($lifetime);
  session_start();
?>

This code doesn't change the lifetime of the session when the user gets back at our site or refreshes the page. The session WILL expire after $lifetime seconds, no matter how many times the user requests the page. So we just overwrite the session cookie as follows:

<?php
  $lifetime=600;
  session_start();
  setcookie(session_name(),session_id(),time()+$lifetime);
?>

And now we have the same session cookie with the lifetime set to the proper value.

由于 PHP 的会话控制在使用 session_set_cookie_params() 时不能正确处理会话生存期,因此我们需要做一些事情来在用户每次访问我们的站点时更改会话到期时间。所以,问题来了。

<?php
  $lifetime=600;
  session_set_cookie_params($lifetime);
  session_start();
?>

当用户返回我们的站点或刷新页面时,此代码不会更改会话的生命周期。无论用户请求页面多少次,会话都将在 $lifetime 秒后过期。因此,我们只需按如下方式覆盖会话 cookie:

<?php
  $lifetime=600;
  session_start();
  setcookie(session_name(),session_id(),time()+$lifetime);
?>

现在我们有相同的会话 cookie,其生命周期设置为正确的值。

My solution:

我的解决方案:

Originally:

起初:

        $cookieParams = session_get_cookie_params();

        session_set_cookie_params(
            $seconds,
            $cookieParams['path'],
            $cookieParams['domain'],
            $cookieParams['secure']
            );

Now:

现在:

        if(isset($_SESSION)) {
            if ($seconds != 0) {
                setcookie(session_name(), session_id(), time() + $seconds);
            } else {
                setcookie(session_name(), session_id(), $seconds);
            }
        } else {
            $cookieParams = session_get_cookie_params();

            session_set_cookie_params(
                $seconds,
                $cookieParams['path'],
                $cookieParams['domain'],
                $cookieParams['secure']
            );
        }

回答by arimas

I have same warning and my code is:

我有同样的警告,我的代码是:

if (isset($_COOKIE['token'])) {
    $vaz = preg_match('/^[-,a-zA-Z0-9]{1,128}$/', $_COOKIE['token']) > 0;
    if ($vaz) {
         session_id($_COOKIE['token']);
    } else {
        setcookie('token', '', (time()-1000),'/');
    }
}
@session_start();
session_set_cookie_params('0', '/', URL, false, TRUE);`  so i add "@"to this lines:` session_id($_COOKIE['token']);`and ` session_set_cookie_params('0', '/', URL, false, TRUE)`and resolve my warning :) my finally code is here`if (isset($_COOKIE['token'])) {
    $vaz = preg_match('/^[-,a-zA-Z0-9]{1,128}$/', $_COOKIE['token']) > 0;
    if ($vaz) {
        @session_id($_COOKIE['token']);
    } else {
        setcookie('token', '', (time()-1000),'/');
    }
}
@session_start();
@session_set_cookie_params('0', '/', URL, false, TRUE);