Blackbam
Dado que PHP en nuestro servidor se actualizó a 7.2 desde 7.0. Recibo la siguiente advertencia (que genera un error) si se realiza una nueva implementación. La razón es probablemente que las sesiones antiguas se vuelven inválidas después de la implementación.
Advertencia: nombre_sesión(): No se puede cambiar el nombre de la sesión cuando la sesión está activa en /var/www/html/model/login/lib/Session.class.php en la línea 137
Advertencia: session_set_cookie_params(): No se pueden cambiar los parámetros de las cookies de sesión cuando la sesión está activa en
/var/www/html/model/login/lib/Session.class.php en la línea 138Advertencia: no se puede modificar la información del encabezado: los encabezados ya enviados por (salida iniciada en /var/www/html/model/login/lib/Session.class.php:137) en /var/www/html/model/login/lib/ Session.class.php en la línea 142
Parece que PHP 7.2 se volvió más estricto en el contexto de la sesión en un contexto determinado. El servidor parece reconocer las sesiones no válidas e intenta destruirlas. Esto es parte de la clase Sesión:
/**
* 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();
}
}
¿Qué ha cambiado en PHP con respecto a las sesiones?
¿Por qué no se permite establecer un nombre de sesión si hay otra sesión activa (de acuerdo con los documentos con session_name, podría cambiar sesiones y comenzar varias sesiones)?
¿Y cómo puedo destruir la sesión en ejecución de manera adecuada?
Investigando más, también encontré la siguiente discusión en GitHub (https://github.com/Icinga/icingaweb2/issues/3185). Confirman que este error se introdujo con PHP 7.2. Desafortunadamente tampoco hay respuesta :-/
Hice un informe de error en php.net y me explicaron que esto no es un error. Sí, en PHP 7.2 ahora se genera una advertencia. Sin embargo, esto nunca funcionó como se pretendía, simplemente fracasó en silencio.
Para crear múltiples sesiones es necesario utilizar session_id()
. Eche un vistazo a esta pregunta relacionada: PHP ¿Cómo puedo crear varias sesiones?
session_name()
así como session_set_cookie_params()
siempre son absurdos si la sesión ya se está ejecutando.
Para la respuesta original echa un vistazo aquí: https://bugs.php.net/bug.php?id=75650&gracias=2
Miracool
Tuve un problema similar pero finalmente encontré una manera de solucionarlo. El siguiente código fue mi primer enfoque que me dio errores.
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();
}
}
Ahora, las versiones anteriores de php pasaron por alto nuestro error (prácticamente estábamos cambiando el nombre y dando propiedades a una sesión que ya existe, lo cual es muy incorrecto. Entonces, ¿cómo resolví este problema?
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();
}
}
Ahora ato el session_set_cookie_params()
justo antes del inicio de la sesión y pruebo si la sesión ya existe antes de hacerlo.
TLDR: si la sesión existe, utilice setcookie(session_name(), session_id(), ...)
más uso session_set_cookie_params(...)
https://www.php.net/manual/en/function.session-set-cookie-params.php#100657
Como el Control de sesión de PHP no maneja correctamente la duración de la sesión cuando se usa session_set_cookie_params(), debemos hacer algo para cambiar el tiempo de vencimiento de la sesión cada vez que el usuario visita nuestro sitio. Entonces, aquí está el problema.
<?php $lifetime=600; session_set_cookie_params($lifetime); session_start(); ?>
Este código no cambia la duración de la sesión cuando el usuario vuelve a nuestro sitio o actualiza la página. La sesión caducará después de $lifetime segundos, sin importar cuántas veces el usuario solicite la página. Así que simplemente sobrescribimos la cookie de sesión de la siguiente manera:
<?php $lifetime=600; session_start(); setcookie(session_name(),session_id(),time()+$lifetime); ?>
Y ahora tenemos la misma cookie de sesión con el tiempo de vida establecido en el valor adecuado.
Mi solución:
Originalmente:
$cookieParams = session_get_cookie_params();
session_set_cookie_params(
$seconds,
$cookieParams['path'],
$cookieParams['domain'],
$cookieParams['secure']
);
Ahora:
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']
);
}
hola donde archivo modifica el codigo de la solucion
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']
);
}
El
if(session_id()) {}
comprobar sugiere quedestroyAbsolute()
espera que algunas vecessession_start()
ha sido llamado y algunas veces no lo ha hecho. tu llamada asession_name()
entonces debe seguir la misma lógica.–Álvaro González
7 de diciembre de 2017 a las 17:19
El comentario “Debe llamarse después de session_start” contradice los documentos de
session_name()
“tienes que llamarsession_name()
[…] antessession_start()
“. Supongo que este código nunca eliminó la sesión con el nombreself::$name
.– Roland Starke
7 de diciembre de 2017 a las 17:22
@RolandStarke De acuerdo con los documentos, session_name también se puede configurar para ESTABLECER o ELEGIR el nombre de la sesión actual. ¿Puede vincular a los documentos ya que no puedo encontrar dónde está documentado?
– Blackbam
7 dic 2017 a las 17:27
Utilizando el máquina de camino de regreso y yendo lo más atrás posible (2001) se puede encontrar la misma cita. “[…] antes de session_start() o session_register()”. Así que supongo que no es una característica nueva. Tal vez en versiones anteriores falló en silencio y ahora hay un error. ¿Podría cerrar la sesión actual y comenzar una nueva? Me gusta
session_write_close(); session_name(self::$name); session_set_cookie_params(...); session_start();
?– Roland Starke
8 de diciembre de 2017 a las 7:22
Tengo este problema cuando actualizo a Drupal 7. Cualquier otra persona que vea esto para Drupal puede buscar aquí.
– bombomb007
15 de julio de 2019 a las 18:44