Note

The online documentation is produced by a web publishing technology created by us to read the documents origins in OpenOffice Writer (ODT) and Microsoft Word (docx) formats and produces native web and PDF versions. In this way we maintain Louder project documentation update and in sync on each of its formats.
Select a Language:
Componente Session
Introducción
El componente Session ofrece principalmente un método orientado a objetos para la administración de persistencia de una aplicación Web. Con una arquitectura basada en adaptadores es posible de manera flexible definir diferentes backend de almacenamiento de sesión a cada aplicación.

Es altamente recomendable utilizar el componente Session para almacenar datos de sesión en vez de utilizar la superglobal $_SESSION. Los métodos estáticos Session::set y Session::get administran la memoria de las aplicaciones de tal forma que los datos de sesión sean completamente independientes a otras aplicaciones que corran en el mismo servidor y sobre el mismo cliente.

Esta independencia elimina posibles problemas de seguridad asociados a la utilización de aplicaciones con una estructura de autenticación y validación de credenciales idéntica.

En el siguiente ejemplo se visualiza como Session separa la persistencia en cada aplicación. Tenemos 2 instancias del Framework en el document root del servidor web, la primera para la intranet y la segunda para la intranet. Cada instancia tiene una serie de aplicaciones asociadas a cada una junto con un backend de sesión diferente.
Ejemplo: Estructura de aplicaciones con diferentes backend de Sesión
intranet/
     apps/
          default/              | memcached
          produccion/           | files
          compras/              | Database:MySQL
extranet/
     apps/
          default/              | files
          reservas/             | Database:Sqlite
          informacion/          | memcached
          produccion/           | files 

En la aplicación existe una variable de sesión llamada "auth", esta variable controla que el usuario final esté autenticado en una aplicación. Normalmente utilizaríamos esta variable usando la superglobal $_SESSION['auth']. Sin embargo el valor de esta variable estaría asociado a nuestro 'session id' y si accedemos a otra aplicación también estaríamos autenticados. Si las reglas del negocio lo permiten esto estaría correcto, pero en la mayoría de casos cada aplicación administra diferentes modelos de seguridad y validación.

El componente Session hace que la misma variable "auth" sea diferente en cada aplicación de forma independiente y en forma transparente para el desarrollador.

En el ejemplo también se visualiza que la aplicación 'produccion' existe tanto en 'intranet' como en 'extranet' sin embargo su finalidad es diferente. El componente Session separa la persistencia de sesión tomando en cuenta que se encuentra en diferentes instancias del Framework así el nombre de la aplicación sea el mismo.
Adaptadores de Sesión
Cada aplicación puede utilizar un backend diferente desacuerdo a las necesidades de la aplicación. El componente Session implementa el patrón Gateway actuando como puerta de enlace al adaptador requerido cuando se efectúan operaciones sobre el estado de la sesión. Una descripción de los backend disponibles es:
Tabla: Adaptadores del componente Session
Adaptador
Descripción
MemcacheOfrece mayor velocidad y rendimiento que los demás backend. El almacenamiento se realiza en memoria RAM por lo que se evita la intensiva lectura/escritura de disco de los demás backend. Su escalabilidad es mayor igualmente.
DatabasePermite realizar el usando una tabla en una base de datos. En el caso de MySQL junto con NDB Cluster puede aumentar la escalabilidad, aunque esto debe ser evaluado de acuerdo a las reglas del negocio. Este tipo de implementación de sesiones aplica el patrón Database Session State.
FilesEs el medio de almacenamiento por defecto de PHP que utiliza el sistema de archivos para guardar los datos de sesión. Optimizaciones al sistema de archivo podrían mejorar el rendimiento.
LouderCacheUtiliza el Louder Cache como backend para almacenar los datos de sesión. De esta forma se puede conseguir un sistema escalable y de alta disponibilidad para almacenar el estado de sesión de una aplicación.


Los adaptadores de sesión implementan la interface SessionInterface:
interface SessionInterface {

     public function getSaveHandler();
     public function initialize();

}
Adaptador de Sesión Memcache
Para activar el adaptador Memcache se debe agregar a la sección application del archivo config.ini de la aplicación lo siguiente:
Ejemplo: Establecer el adaptador de sesión a Memcached
sessionAdapter = memcache
sessionSavePath = "tcp://127.0.0.1:11211?persistent=1&weight=2&timeout=2"
Adaptador de Sesión Database
Para usar el adaptador de sesiones usando una tabla de la bases de datos se debe agregar a la sección application del archivo config.ini de la aplicación lo siguiente:
Ejemplo: Establecer el adaptador de sesión a Database
sessionAdapter = database
sessionSavePath = "mysql:host=127.0.0.1;username=root;password=mypass;name=mydb"

En la base de datos seleccionada se debe crear la siguiente tabla:
CREATE TABLE `session_data` (
  `id` int(18) NOT NULL auto_increment,
  `session_id` varchar(35) NOT NULL,
  `data` text,
  `timelife` int(15) default NULL,
  PRIMARY KEY  (`id`),
  KEY `session_id` (`session_id`)
);

Un collector de datos de sesión no utilizados es implementado en este adaptador para los datos de sesión que hayan expirado. Sesiones que tengan más de 24 horas de expiración serán eliminadas de la tabla session_data.
Adaptador de sesión Files
Es el adaptador por defecto y no es necesario realizar configuraciones adicionales para establecerlo. La ruta de almacenamiento de archivos puede modificarse buscando aprovechar optimizaciones del sistema de archivos.
Ejemplo: Establecer el adaptador de sesión a files
sessionAdapter = files
sessionSavePath = "/path/to/session/data"

Sistemas de archivos como ReiserFS en Linux pueden mejorar el rendimiento ya que estos administran mejor archivos pequeños.
Adaptador de sesión Louder Cache
Para usar este adaptador LouderCache debe estar instalado como una librería en la instancia del framework.
Comportamiento de Sesiones
Las sesiones Kumbia Enterprise Framework son inicializadas en un managed environment (entorno administrado) con lo que el punto de inicialización y finalización de sesiones no debe ser un problema para el desarrollador. Los datos en el entorno de persistencia son serializados/deserializados exactamente cuando es necesario, un mal manejo de esto podría generar perdida de datos si se realizase manualmente, especialmente cuando se almacenan objetos ó se trabaja con Web services. El Framework implementa el patrón Server Session State para conceptualmente administrar el estado de persistencia de la aplicación.

Las sesiones se inicializan justo después de cargar la clase controladora, cualquier procedimiento previo a esto en donde se interactúe con sesiones puede producir resultados confusos. Los plugins de controlador que implementen el método Plugin::beforeDispatchLoop() son un ejemplo de esto.
Consideraciones de Seguridad
Las sesiones son un blanco de ataques informáticos entre ellos estan los Hijacking ó Fixation. Una aplicación Web mal diseñada puede ser blanco de ello, independiente del Framework utilizado para su desarrollo. Una de las mejores formas de evitar esto es usar sessiones basadas en cookies usando la directiva de configuración de php session.use_cookies = 1 y además session.use_only_cookies = 1.

Una buena practica adicional a lo anterior es ocasionalmente validar el tipo de dato de los valores que provengan de sesiones usando el componente Filter en casos en los que los valores de sesión vayan a ser utilizados para insertar datos en la base de datos:
Ejemplo: Filtrar los datos de session para evitar hijacking
<?php

class CustomerController extends ApplicationController {

     public function beforeFilter(){
          $valor = Session::get("valor", "int");
          $nombre = Session::get("nombre", "alpha");
     }

}
Variables de sesión
El componente Session permite la administración de variables de sesión que corresponden a valores simples que se referencia mediante un índice ó nombre clave.

Las variables de sesión se almacenan en espacios de memoria independientes por aplicación con lo que se evita situaciones confusas al utilizar índices comunes en diferentes aplicaciones que se usen en una mismo contexto de sesión con un usuario.
API del Componente Session
public static void initSessionData()
Inicializa los datos de sesión es decir los deserializa y crea un vector interno listo para usar. Usualmente este método no es invocada por el desarrollador y es implícitamente llamado al usar getData ó setData.

public static void storeSessionData()
Este método es llamado como un register_shutdown_function y serializa los datos de sesión.

public static void setData(string $index, mixed $value)
Permite establecer un valor de sesión $value mediante la llave $index.

public static mixed getData(string $index)
Permite obtener un valor de sesión de un valor establecido con la llave $index.

public static void set(string $index, mixed $value)
Establece el valor de una variable de sesión usando la clave $index y el valor $value.

public static mixed get(string $index)
Obtener el valor de una variable de sesión usando la clave $index.

public static void unsetData(string $index)
Eliminar un variable de sesión usando la clave $index

public static mixed issetData(string $index)
Permite conocer si una variable de sesión ya existe. Este método devuelve un valor booleano true cuando ya existe y false en el caso contrario.

public static void isLocked()
Permite saber si la sesión esta bloqueada para escritura.

public static boolean isStarted()
Permite saber si ya se ha inicializado el adaptador de sesión y todo el contexto de sesión como tal.

public static void startSession()
Inicia el contexto de sesión incluyendo el adaptador de administración de sesiones.
SessionNamespace
La clase SessionNamespace es un subcomponente de Session el cual permite la utilización de datos de sesión de manera orientada a objetos y manteniendo la independización de la memoria persistente de las aplicaciones desarrolladas.

Al crear un Namespace se asigna un nombre único que permite identificar el espacio de nombres en toda la aplicación. Los identificadores de los Namespaces deben ser Strings, estos no tienen conflicto con los nombres utilizados en los métodos Session::set y Session::get.

Los objetos de sesión creados en los SessionNamespace son objetos administrables que son automáticamente serializados/deserializados al guardarse en el backend de sesión. Además, estos objetos tienen la propiedad de poderse bloquear/desbloquear para evitar que su valor sea modificado por error ó por componentes de terceros.

En el siguiente ejemplo se muestra un SessionNamespace para almacenar la información relevante a los datos del usuario al inicio de una sesión. Como se ilustra, no es necesario ejecutar ningún procedimiento para almacenar los cambios del Namespace, el nombre UserData es usado posteriormente para recuperar la información del mismo.
Ejemplo: Utilización de SessionNamespace
<?php

class LoginController extends ApplicationController {

     public function processLoginAction(){
          $userData = SessionNamespace::add('UserData', 'name', 'John Smith');
          $userData->setRole("Administrator");
          $userData->setLogin("j.smith");
     }

     public function anotherAction(){
          $userData = SessionNamespace::get('UserData');
          if($userData->getRole()=="Administrator"){
               Flash::notice("Bienvenido, su login es ".$userData->getLogin());
          }
          SessionNamespace::lock('UserData');
     }

     public function theLastAction(){
          $userData = SessionNamespace::get('UserData');
          try  {
               $userData->setRole("Public");
          }
          catch(SessionException $e){
               Flash::error("Error: La sesi&oacute;n esta bloqueada");
          }
     }
}

Para obtener/establecer los valores del namespace se debe utilizar getters/setters implícitos en el objeto devuelto por SessionNamespace::add ó SessionNamespace::get. Estos utilizan notación camelizada y la utilización del mismo ayuda a que el comportamiento de este sea el esperado. Los objetos creados son instancias de NamespaceContainer quien además proporciona los métodos setValue y getValue que permiten obtener/establecer los valores del namespace dinámicamente mediante claves.
API de SessionNameSpace
public static NamespaceContainer add(string $namespace, string $property=null, mixed $value=null)
Crea un nuevo SessionNamespace ó devuelve uno existe. Es posible establecer un primer valor usando el parámetro $property y $value.

public static void lock(string $namespace)
Bloquea el SessionNamespace para evitar cambios en sus datos internos.

public static void unlock(string $namespace)
Desbloquea el SessionNamespace permitiendo cambios en sus datos internos.

public static NamespaceContainer get(string $namespace)
Obtiene un SessionNamespace existente.

public static boolean exists(string $namespace)
Indica si un SessionNamespace ya existe ó no.

public static void reset(string $namespace)
Elimina los datos del SessionNamespace.

public static void drop(string $namespace)
Elimina el SessionNamespace.