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. Надеюсь, это поможет.