El almacenamiento de sesiones predeterminado de Symfony2 escribe la información de la sesión en archivo(s). La mayoría desde medianos hasta grandes sitios web utilizan una base de datos para almacenar valores de sesión en lugar de archivos, porque las bases de datos son más fáciles de usar y escalar en un entorno web multiservidor.
Symfony2 ha incorporado una solución para el almacenamiento de la sesión en la base de datos denominada Symfony\Component\HttpFoundation\SessionStorage\PdoSessionStorage. Para usarla, sólo tienes que cambiar algunos parámetros en config.yml (o el formato de configuración de tu elección):
Nuevo en la versión 2.1: En Symfony 2.1 la clase y el espacio de nombres se han modificado significativamente. Ahora puedes encontrar las clases de almacenamiento de sesión en el espacio de nombres Session\Storage: Symfony\Component\HttpFoundation\Session\Storage. Además ten en cuenta que en Symfony 2.1 debes configurar handler_id no storage_id como en Symfony2.0. Abajo, notarás que ya no se utiliza %sesión.storage.options%.
# app/config/config.yml
framework:
session:
# ...
handler_id: session.handler.pdo
parameters:
pdo.db_options:
db_table: session
db_id_col: session_id
db_data_col: session_value
db_time_col: session_time
services:
pdo:
class: PDO
arguments:
dsn: "mysql:dbname=mydatabase"
user: myuser
password: mypassword
session.handler.pdo:
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
arguments: ["@pdo", "%pdo.db_options%"]
<!-- app/config/config.xml -->
<framework:config>
<framework:session handler-id="session.handler.pdo" cookie-lifetime="3600" auto-start="true"/>
</framework:config>
<parameters>
<parameter key="pdo.db_options" type="collection">
<parameter key="db_table">session</parameter>
<parameter key="db_id_col">session_id</parameter>
<parameter key="db_data_col">session_value</parameter>
<parameter key="db_time_col">session_time</parameter>
</parameter>
</parameters>
<services>
<service id="pdo" class="PDO">
<argument>mysql:dbname=mydatabase</argument>
<argument>myuser</argument>
<argument>mypassword</argument>
</service>
<service id="session.handler.pdo" class="Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler">
<argument type="service" id="pdo" />
<argument>%pdo.db_options%</argument>
</service>
</services>
// app/config/config.php
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
$container->loadFromExtension('framework', array(
...,
'session' => array(
// ...,
'handler_id' => 'session.handler.pdo',
),
));
$container->setParameter('pdo.db_options', array(
'db_table' => 'session',
'db_id_col' => 'session_id',
'db_data_col' => 'session_value',
'db_time_col' => 'session_time',
));
$pdoDefinition = new Definition('PDO', array(
'mysql:dbname=mydatabase',
'myuser',
'mypassword',
));
$container->setDefinition('pdo', $pdoDefinition);
$storageDefinition = new Definition('Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler', array(
new Reference('pdo'),
'%pdo.db_options%',
));
$container->setDefinition('session.handler.pdo', $storageDefinition);
Con la configuración dada, la configuración de conexión de la base de datos únicamente se define para la conexión de almacenamiento de sesión. Esto está bien cuando utilizas una base de datos para los datos de sesión.
Pero si deseas almacenar los datos de sesión en la misma base que el resto de los datos de tu proyecto, puedes utilizar la configuración de conexión de parameters.yml refiriendo los parámetros relacionados con la base de datos definidos allí:
pdo:
class: PDO
arguments:
- "mysql:host=%database_host%;port=%database_port%;dbname=%database_name%"
- "%database_user%"
- "%database_password%"
<service id="pdo" class="PDO">
<argument>mysql:host=%database_host%;port=%database_port%;dbname=%database_name%</argument>
<argument>%database_user%</argument>
<argument>%database_password%</argument>
</service>
$pdoDefinition = new Definition('PDO', array(
'mysql:host=%database_host%;port=%database_port%;dbname=%database_name%',
'%database_user%',
'%database_password%',
));
La declaración SQL necesaria para crear la tabla en la base de datos podría ser similar a la siguiente (MySQL):
CREATE TABLE `session` (
`session_id` varchar(255) NOT NULL,
`session_value` text NOT NULL,
`session_time` int(11) NOT NULL,
PRIMARY KEY (`session_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Para PostgreSQL, la declaración debe tener este aspecto:
CREATE TABLE session (
session_id character varying(255) NOT NULL,
session_value text NOT NULL,
session_time integer NOT NULL,
CONSTRAINT session_pkey PRIMARY KEY (session_id)
);
Para MSSQL, la declaración se podría parecer a la siguiente:
CREATE TABLE [dbo].[session](
[session_id] [nvarchar](255) NOT NULL,
[session_value] [ntext] NOT NULL,
[session_time] [int] NOT NULL,
PRIMARY KEY CLUSTERED(
[session_id] ASC
) WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]