2011/05/27

Sesiones PHP a lo campestre II. Seamos civilizados

En contra de lo que el título puede indicar, a priori vamos a ver el método "correcto" de almacenar la información de nuestra aplicación en el pseudo-array $_SESSION de PHP.

A la hora de almacenar los datos, siempre podemos usar el método que aparece en todos los sitios, incluida la documentación de http://php.net/ donde de forma simplista dice
"Para almacenar una variable en la sesión, haz $_SESSION['variable'] = $valor;"
Muy bonito y sencillo, pero las cosas no se pueden reducir tanto. Imagináos el escenario de que en un mismo servidor hay varias aplicaciones web con PHP funcionando. Inicialmente creamos una sesión en una aplicación que alegremente nos mete en nuestra sesión un valor 'id' con valor 3 mediante $_SESSION['id'] = 3;

Hasta aquí, bien, todo funciona. Ahora abrimos una segunda aplicación dentro del mismo servidor que usa esa misma variable de sesión, pero ahora con valor 'nulo' mediante $_SESSION['id'] = 'nulo';

Volvemos a la primera aplicación y cuando ésta pregunta por el valor de 'id' en la sesión NO RECIBE el valor 3 que es lo que espera, si no 'nulo'. Ea!, ahora vuélvete loco depurando o directamente vete a por una pistola para pegarte un tiro, porque no lo vas a encontrar...

Esto se arregla usando la misma técnica que se usa en javascript para optimizar el ámbito de las variables. Lo que hay que hacer es crear un ámbito de cada aplicación dentro de la sesión. Para ello, en vez de asignar un valor directamente a $_SESSION, vamos a crear una nueva varible dentro PERO DE TIPO ARRAY con nombre, siendo originales, el de nuestra aplicación. Así, todo quedaría así:
// Inicia la sesión
session_start();
// Crea el contexto
if(!isset($_SESSION['aplicacion1'])) $_SESSION['aplicacion1'] = array(); 

$_SESSION['aplicacion1']['id'] = 3;
// Ahora sí que cuando se lea la segunda vez valdrá 3
Con ésto, nos aseguramos que todo va a funcionar como debe sin tener dolores de cabeza.

Visto lo visto, si queremos realizar la misma barbaridad que vimos ayer accediendo a los valores de la sesión usando el contexto que hemos creado, habría que cambiarlo por
// Coge los valores de la sesión para nuestro contexto
$aplicacion = 'aplicacion1';
$res   = preg_match('/' . $aplicacion . '\|a\:\d+\:\{(.*)\};?/i', $txt, $data);
if($res) $txt    = $data[1];
else die("No hay sesión iniciada");

// Lee el valor de la variable id del contexto aplicacion1
$var   = 'id';
$res   = preg_match('/"' . $var . '"\;s\:\d*\:\"(\d+)\";/i', $txt, $data);
if($res) $idt    = $data[1];
Los cambios son pocos pero sutiles. Ahora, nuestra variable estará encerrada entre comas (antes no lo estaba) y el separador entre el nombre de la variable y el valor pasa de ser dos puntos a ser punto y coma.

Cuidadín con lo que haceís ya que en ese fichero de sesión se almacenan todas las sesiones iniciadas por ese cliente, tanto para la "aplicacion1" como para la "aplicacion2" siguiendo el ejemplo del principio.

No hay comentarios:

Publicar un comentario