web-dev-qa-db-ja.com

PHP 7.2警告:「セッションがアクティブな場合、セッション名を変更できません」

PHPはサーバーで7.0から7.2にアップグレードされました。新しい展開が行われると、次の警告(エラーにつながる)が表示されます。おそらく、古いセッションが無効になるためです。展開後。

警告:session_name():セッションがアクティブな場合、セッション名は変更できません/var/www/html/model/login/lib/Session.class.php on line 137

警告:session_set_cookie_params():セッションがアクティブな場合、セッションCookieパラメーターを変更できない/var/www/html/model/login/lib/Session.class.php on line 138

警告:ヘッダー情報は変更できません-ヘッダーは既に/ var/www/html/model/login/lib /にある(/var/www/html/model/login/lib/Session.class.php:137で開始された)によって送信されました142行目のSession.class.php

PHP 7.2は特定のコンテキストのセッションのコンテキストでより厳格になりました。サーバーは無効なセッションを認識し、それらを破棄しようとします。これは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();
    }
}

セッションに関してPHPで何が変更されましたか?

別のセッションがアクティブな場合、セッション名を設定できないのはなぜですか(session_nameのドキュメントによると、セッションを変更して複数のセッションを開始できます)?

そして、実行中のセッションを適切に破棄するにはどうすればよいですか?

さらなる調査を行うと、GitHubで次の議論も見つかりました( https://github.com/Icinga/icingaweb2/issues/3185 )。 彼らは、このエラーがPHP 7.2)で導入されたことを確認します。残念ながら、答えもありません:-/

15
Blackbam

Php.netでバグレポートを作成しましたが、これはバグではないと説明されました。 はいPHP 7.2警告が生成されるようになりました。しかし、これは意図したとおりに機能せず、静かに失敗した/.

複数のセッションを作成するには、session_id()を使用する必要があります。この関連する質問をご覧ください: PHP複数のセッションを作成するにはどうすればよいですか?

セッションがすでに実行されている場合、session_name()session_set_cookie_params()は常に無意味です。

元の答えについては、こちらをご覧ください: https://bugs.php.net/bug.php?id=75650&thanks=2

8
Blackbam

私は同様の問題を抱えていましたが、最終的に方法を見つけました。以下のコードは、エラーを出した最初のアプローチです。

_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();
    }
}
_

これで、以前のバージョンの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();
         }    
    }
_

セッション開始の直前にsession_set_cookie_params()をバインドし、そうする前にセッションが既に存在するかどうかをテストします。

5
Miracool

TLDR:セッションが存在する場合は、setcookie(session_name(), session_id(), ...)を使用し、そうでない場合はsession_set_cookie_params(...)を使用します

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

Session_set_cookie_params()を使用すると、PHPのセッションコントロールはセッションの有効期間を正しく処理しないため、ユーザーがサイトにアクセスするたびにセッションの有効期限を変更するために何かを行う必要があります。だから、ここに問題があります。

<?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があります。

私の解決策:

元々:

        $cookieParams = session_get_cookie_params();

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

今:

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