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.
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
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:
/**
* 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?
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)?
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 :-/
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.
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_name()
as well as session_set_cookie_params()
are always nonesense if the session is already running.
For the original answer have a look here: https://bugs.php.net/bug.php?id=75650&thanks=2
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?
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.
TLDR: if the session exists, use setcookie(session_name(), session_id(), ...)
else use session_set_cookie_params(...)
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.
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']
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With