PHP 7.2 Предупреждение: "Невозможно изменить имя сеанса при активном сеансе"

Так как PHP на нашем сервере был обновлен до 7,2 с 7,0. Я получаю следующее предупреждение (которое приводит к ошибке), если выполняется новое развертывание. Возможно, причина в том, что старые сеансы становятся недействительными после развертывания.

Предупреждение: session_name(): невозможно изменить имя сеанса, когда сеанс активен в/var/www/html/model/login/lib/Session.class.php в строке 137.

Предупреждение: session_set_cookie_params(): невозможно изменить параметры cookie сеанса, когда сеанс активен в/var/www/html/model/login/lib/Session.class.php в строке 138.

Предупреждение: невозможно изменить информацию заголовка - заголовки уже отправлены (вывод начался с /var/www/html/model/login/lib/Session.class.php:137) в /var/www/html/model/login/lib/Session.class.php в строке 142

Похоже, что 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 относительно сессий?

Почему нельзя устанавливать имя сеанса, если активен другой сеанс (в соответствии с документами с именем_сессии, я могу изменить сеанс и запустить несколько сеансов)?

И как я могу соответствующим образом уничтожить запущенную сессию?

Проводя дальнейшие исследования, я также нашел следующее обсуждение на GitHub (https://github.com/Icinga/icingaweb2/issues/3185). Они подтверждают, что эта ошибка была введена в PHP 7.2. К сожалению, также нет ответа: -/

Ответ 1

Я сделал отчет об ошибке на php.net, и они объяснили, что это не ошибка. Да, в PHP 7.2 теперь генерируется предупреждение. Однако это никогда не работало как задумано, это просто молча провалилось.

Для создания нескольких сессий необходимо использовать session_id(). Посмотрите на этот связанный вопрос: PHP Как я могу создать несколько сессий?

session_name() а также session_set_cookie_params() всегда бессмысленны, если сеанс уже запущен.

Для оригинального ответа посмотрите здесь: https://bugs.php.net/bug.php?id=75650&thanks=2.

Ответ 2

У меня была аналогичная проблема, но, наконец, нашла путь. Код ниже был моим первым подходом, который дал мне ошибки.

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() непосредственно перед началом сеанса, и я тестирую, если сеанс уже существует до этого.

Ответ 3

TLDR: если сеанс существует, используйте setcookie(session_name(), session_id(), ...), иначе используйте session_set_cookie_params(...)

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

Поскольку PHP Session Control не обрабатывает время жизни сессии правильно при использовании session_set_cookie_params() нам нужно что-то сделать в Чтобы изменить время истечения сеанса каждый раз, когда пользователь посещает наш сайт. Итак, здесь проблема.

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

Этот код не меняет время жизни сеанса, когда пользователь возвращается на наш сайт или обновляет страницу. Сессия истечет после $ жизни секунд, независимо от того, сколько раз пользователь запрашивает страница. Поэтому мы просто перезаписываем куки файл сессии следующим образом:

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

Ответ 4

У меня php7.2 после обновления, но с установленным mod_php56. Таким образом, не было никаких проблем после того, как нашел это и заменил на mod_php72. Надеюсь, это поможет.