diff --git a/_build/redirection_map b/_build/redirection_map
index 6d591d7ffc5..8b09f4ff0cc 100644
--- a/_build/redirection_map
+++ b/_build/redirection_map
@@ -479,3 +479,5 @@
/components/translation/custom_formats https://github.com/symfony/translation
/components/translation/custom_message_formatter https://github.com/symfony/translation
/components/routing https://github.com/symfony/routing
+/doctrine/pdo_session_storage /session/database
+/doctrine/mongodb_session_storage /session/database
diff --git a/doctrine.rst b/doctrine.rst
index abd1b400bfb..b49e70ed407 100644
--- a/doctrine.rst
+++ b/doctrine.rst
@@ -853,10 +853,9 @@ Learn more
doctrine/custom_dql_functions
doctrine/dbal
doctrine/multiple_entity_managers
- doctrine/pdo_session_storage
- doctrine/mongodb_session_storage
doctrine/resolve_target_entity
doctrine/reverse_engineering
+ session/database
testing/database
.. _`Doctrine`: https://www.doctrine-project.org/
diff --git a/doctrine/mongodb_session_storage.rst b/doctrine/mongodb_session_storage.rst
deleted file mode 100644
index 7ec897bf0a1..00000000000
--- a/doctrine/mongodb_session_storage.rst
+++ /dev/null
@@ -1,31 +0,0 @@
-How to Use MongoDbSessionHandler to Store Sessions in a MongoDB Database
-========================================================================
-
-The default Symfony session storage writes the session information to files.
-Some medium to large websites use a NoSQL database called MongoDB to store the
-session values instead of files, because databases are easier to use and scale
-in a multi-webserver environment.
-
-Symfony has a built-in solution for NoSQL database session storage called
-:class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MongoDbSessionHandler`.
-To use this, you will need to:
-
-A) Register a ``MongoDbSessionHandler`` service;
-
-B) Configure this under ``framework.session.handler_id`` configuration.
-
-To see how to configure a similar handler, see :doc:`/doctrine/pdo_session_storage`.
-
-Setting Up the MongoDB Collection
----------------------------------
-
-You do not need to do anything to initialize your session collection. However, you
-may want to add an index to improve garbage collection performance. From the
-`MongoDB shell`_:
-
-.. code-block:: javascript
-
- use session_db
- db.session.ensureIndex( { "expires_at": 1 }, { expireAfterSeconds: 0 } )
-
-.. _MongoDB shell: https://docs.mongodb.com/manual/mongo/
diff --git a/doctrine/pdo_session_storage.rst b/doctrine/pdo_session_storage.rst
deleted file mode 100644
index 8123a68460d..00000000000
--- a/doctrine/pdo_session_storage.rst
+++ /dev/null
@@ -1,276 +0,0 @@
-.. index::
- single: Session; Database Storage
-
-How to Use PdoSessionHandler to Store Sessions in the Database
-==============================================================
-
-The default Symfony session storage writes the session information to files.
-Most medium to large websites use a database to store the session values
-instead of files, because databases are easier to use and scale in a
-multiple web server environment.
-
-Symfony has a built-in solution for database session storage called
-:class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\PdoSessionHandler`.
-To use it, first register a new handler service:
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- # config/services.yaml
- services:
- # ...
-
- Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler:
- arguments:
- - 'mysql:dbname=mydatabase; host=myhost; port=myport'
- - { db_username: myuser, db_password: mypassword }
-
- # If you're using Doctrine & want to re-use that connection, then:
- # comment-out the above 2 lines and uncomment the line below
- # - !service { class: PDO, factory: ['@database_connection', 'getWrappedConnection'] }
- # If you get transaction issues (e.g. after login) uncomment the line below
- # - { lock_mode: 1 }
-
- .. code-block:: xml
-
-
-
-
-
-
-
- mysql:dbname=mydatabase, host=myhost
-
- myuser
- mypassword
-
-
-
-
-
- .. code-block:: php
-
- // config/services.php
- use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
-
- $storageDefinition = $container->autowire(PdoSessionHandler::class)
- ->setArguments([
- 'mysql:dbname=mydatabase; host=myhost; port=myport',
- ['db_username' => 'myuser', 'db_password' => 'mypassword'],
- ])
- ;
-
-.. tip::
-
- Configure the database credentials
- :ref:`using environment variables `
- or as a :doc:`secret ` to make your application
- more secure.
-
-Next, tell Symfony to use your service as the session handler:
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- # config/packages/framework.yaml
- framework:
- session:
- # ...
- handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
-
- .. code-block:: xml
-
-
-
-
-
-
-
- .. code-block:: php
-
- // config/packages/framework.php
- use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
-
- // ...
- $container->loadFromExtension('framework', [
- // ...
- 'session' => [
- // ...
- 'handler_id' => PdoSessionHandler::class,
- ],
- ]);
-
-Configuring the Table and Column Names
---------------------------------------
-
-This will expect a ``sessions`` table with a number of different columns.
-The table name, and all of the column names, can be configured by passing
-a second array argument to ``PdoSessionHandler``:
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- # config/services.yaml
- services:
- # ...
-
- Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler:
- arguments:
- - 'mysql:dbname=mydatabase; host=myhost; port=myport'
- - { db_table: 'sessions', db_username: 'myuser', db_password: 'mypassword' }
-
- .. code-block:: xml
-
-
-
-
-
-
-
- mysql:dbname=mydatabase, host=myhost
-
- sessions
- myuser
- mypassword
-
-
-
-
-
- .. code-block:: php
-
- // config/services.php
- use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
- // ...
-
- $container->autowire(PdoSessionHandler::class)
- ->setArguments([
- 'mysql:dbname=mydatabase; host=myhost; port=myport',
- ['db_table' => 'sessions', 'db_username' => 'myuser', 'db_password' => 'mypassword']
- ])
- ;
-
-These are parameters that you can configure:
-
-``db_table`` (default ``sessions``):
- The name of the session table in your database;
-
-``db_id_col`` (default ``sess_id``):
- The name of the id column in your session table (VARCHAR(128));
-
-``db_data_col`` (default ``sess_data``):
- The name of the value column in your session table (BLOB);
-
-``db_time_col`` (default ``sess_time``):
- The name of the time column in your session table (INTEGER);
-
-``db_lifetime_col`` (default ``sess_lifetime``):
- The name of the lifetime column in your session table (INTEGER).
-
-.. _example-sql-statements:
-
-Preparing the Database to Store Sessions
-----------------------------------------
-
-Before storing sessions in the database, you must create the table that stores
-the information. The session handler provides a method called
-:method:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\PdoSessionHandler::createTable`
-to set up this table for you according to the database engine used::
-
- try {
- $sessionHandlerService->createTable();
- } catch (\PDOException $exception) {
- // the table could not be created for some reason
- }
-
-If you prefer to set up the table yourself, these are some examples of the SQL
-statements you may use according to your specific database engine.
-
-A great way to run this on production is to generate an empty migration, and then
-add this SQL inside:
-
-.. code-block:: terminal
-
- $ php bin/console doctrine:migrations:generate
-
-Find the correct SQL below and put it inside that file. Then execute it with:
-
-.. code-block:: terminal
-
- $ php bin/console doctrine:migrations:migrate
-
-MySQL
-~~~~~
-
-.. code-block:: sql
-
- CREATE TABLE `sessions` (
- `sess_id` VARCHAR(128) NOT NULL PRIMARY KEY,
- `sess_data` BLOB NOT NULL,
- `sess_time` INTEGER UNSIGNED NOT NULL,
- `sess_lifetime` INTEGER UNSIGNED NOT NULL
- ) COLLATE utf8mb4_bin, ENGINE = InnoDB;
-
-.. note::
-
- A ``BLOB`` column type can only store up to 64 kb. If the data stored in
- a user's session exceeds this, an exception may be thrown or their session
- will be silently reset. Consider using a ``MEDIUMBLOB`` if you need more
- space.
-
-PostgreSQL
-~~~~~~~~~~
-
-.. code-block:: sql
-
- CREATE TABLE sessions (
- sess_id VARCHAR(128) NOT NULL PRIMARY KEY,
- sess_data BYTEA NOT NULL,
- sess_time INTEGER NOT NULL,
- sess_lifetime INTEGER NOT NULL
- );
-
-Microsoft SQL Server
-~~~~~~~~~~~~~~~~~~~~
-
-.. code-block:: sql
-
- CREATE TABLE [dbo].[sessions](
- [sess_id] [nvarchar](255) NOT NULL,
- [sess_data] [ntext] NOT NULL,
- [sess_time] [int] NOT NULL,
- [sess_lifetime] [int] NOT NULL,
- PRIMARY KEY CLUSTERED(
- [sess_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]
-
-.. caution::
-
- If the session data doesn't fit in the data column, it might get truncated
- by the database engine. To make matters worse, when the session data gets
- corrupted, PHP ignores the data without giving a warning.
-
- If the application stores large amounts of session data, this problem can
- be solved by increasing the column size (use ``BLOB`` or even ``MEDIUMBLOB``).
- When using MySQL as the database engine, you can also enable the `strict SQL mode`_
- to be notified when such an error happens.
-
-.. _`strict SQL mode`: https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html
diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst
index f0d88114f8f..2c6a9aad446 100644
--- a/reference/configuration/framework.rst
+++ b/reference/configuration/framework.rst
@@ -1233,6 +1233,8 @@ The service id used for session storage. The ``session.storage`` service
alias will be set to this service id. This class has to implement
:class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageInterface`.
+.. _config-framework-session-handler-id:
+
handler_id
..........
@@ -1240,63 +1242,8 @@ handler_id
The service id used for session storage. The default ``null`` value means to use
the native PHP session mechanism. Set it to ``'session.handler.native_file'`` to
-let Symfony manage the sessions itself using files to store the session
-metadata.
-
-You can also configure the session handler with a DSN. For example:
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- # config/packages/framework.yaml
- framework:
- session:
- # ...
- handler_id: 'redis://localhost'
- handler_id: '%env(REDIS_URL)%'
- handler_id: '%env(resolve:DATABASE_URL)%'
- handler_id: 'file://%kernel.project_dir%/var/sessions'
-
- .. code-block:: xml
-
-
-
-
-
-
-
-
-
-
- .. code-block:: php
-
- // config/packages/framework.php
- $container->loadFromExtension('framework', [
- 'session' => [
- // ...
- 'handler_id' => 'redis://localhost',
- 'handler_id' => '%env(REDIS_URL)%',
- 'handler_id' => '%env(resolve:DATABASE_URL)%',
- 'handler_id' => 'file://%kernel.project_dir%/var/sessions',
- ],
- ]);
-
-.. versionadded:: 4.4
-
- The option to configure the session handler with a DSN was introduced in Symfony 4.4.
-
-If you prefer to make Symfony store sessions in a database read
-:doc:`/doctrine/pdo_session_storage`.
+let Symfony manage the sessions itself using files to store the session metadata.
+You can also :doc:`store sessions in a database `.
.. _name:
diff --git a/session.rst b/session.rst
index 265a9820f8f..b2c38baa68d 100644
--- a/session.rst
+++ b/session.rst
@@ -121,9 +121,8 @@ session metadata files:
]);
Check out the Symfony config reference to learn more about the other available
-:ref:`Session configuration options `. Also, if you
-prefer to store session metadata in a database instead of the filesystem,
-check out this article: :doc:`/doctrine/pdo_session_storage`.
+:ref:`Session configuration options `. You can also
+:doc:`store sessions in a database `.
Basic Usage
-----------
@@ -219,7 +218,9 @@ More about Sessions
.. toctree::
:maxdepth: 1
- /doctrine/pdo_session_storage
+ session/sessions_directory
+ session/avoid_session_start
+ session/database
session/locale_sticky_session
session/php_bridge
session/proxy_examples
diff --git a/session/database.rst b/session/database.rst
new file mode 100644
index 00000000000..29cd29f8d30
--- /dev/null
+++ b/session/database.rst
@@ -0,0 +1,600 @@
+.. index::
+ single: Session; Database Storage
+
+Store Sessions in a Database
+============================
+
+Symfony stores sessions in files by default. If your application is served by
+multiple servers, you'll need to use instead a database to make sessions work
+across different servers.
+
+Symfony can store sessions in all kinds of databases (relational, NoSQL and
+key-value) but recommends key-value databases like Redis to get best performance.
+
+Store Sessions in a key-value Database (Redis)
+----------------------------------------------
+
+This section assumes that you have a fully-working Redis server and have also
+installed and configured the `phpredis extension`_.
+
+First, define a Symfony service for the connection to the Redis server:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # config/services.yaml
+ services:
+ # ...
+ Redis:
+ # you can also use \RedisArray, \RedisCluster or \Predis\Client classes
+ class: Redis
+ calls:
+ - method: connect
+ arguments:
+ - '%env(REDIS_HOST)%'
+ - '%env(int:REDIS_PORT)%'
+
+ # uncomment the following if your Redis server requires a password
+ # - method: auth
+ # arguments:
+ # - '%env(REDIS_PASSWORD)%'
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+ %env(REDIS_HOST)%
+ %env(int:REDIS_PORT)%
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ use Symfony\Component\DependencyInjection\Reference;
+
+ // ...
+ $container
+ // you can also use \RedisArray, \RedisCluster or \Predis\Client classes
+ ->register('Redis', \Redis::class)
+ ->addMethodCall('connect', ['%env(REDIS_HOST)%', '%env(int:REDIS_PORT)%'])
+ // uncomment the following if your Redis server requires a password:
+ // ->addMethodCall('auth', ['%env(REDIS_PASSWORD)%'])
+ ;
+
+Now pass this ``\Redis`` connection as an argument of the service associated to the
+:class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\RedisSessionHandler`.
+This argument can also be a ``\RedisArray``, ``\RedisCluster``, ``\Predis\Client``,
+and ``RedisProxy``:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # config/services.yaml
+ services:
+ # ...
+ Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler:
+ arguments:
+ - '@Redis'
+ # you can optionally pass an array of options. The only option is 'prefix',
+ # which defines the prefix to use for the keys to avoid collision on the Redis server
+ # - { prefix: 'my_prefix' }
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ // config/services.php
+ use Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler;
+
+ $container
+ ->register(RedisSessionHandler::class)
+ ->addArgument(
+ new Reference('Redis'),
+ // you can optionally pass an array of options. The only option is 'prefix',
+ // which defines the prefix to use for the keys to avoid collision on the Redis server:
+ // ['prefix' => 'my_prefix'],
+ );
+
+Next, use the :ref:`handler_id `
+configuration option to tell Symfony to use this service as the session handler:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # config/packages/framework.yaml
+ framework:
+ # ...
+ session:
+ handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ // config/packages/framework.php
+ use Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler;
+
+ // ...
+ $container->loadFromExtension('framework', [
+ // ...
+ 'session' => [
+ 'handler_id' => RedisSessionHandler::class,
+ ],
+ ]);
+
+That's all! Symfony will now use your Redis server to read and write the session
+data. The main drawback of this solution is that Redis does not perform session
+locking, so you can face *race conditions* when accessing sessions. For example,
+you may see an *"Invalid CSRF token"* error because two requests were made in
+parallel and only the first one stored the CSRF token in the session.
+
+.. seealso::
+
+ If you use Memcached instead of Redis, follow a similar approach but replace
+ ``RedisSessionHandler`` by :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MemcachedSessionHandler`.
+
+Store Sessions in a Relational Database (MySQL, PostgreSQL)
+-----------------------------------------------------------
+
+Symfony includes a :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\PdoSessionHandler`
+to store sessions in relational databases like MySQL and PostgreSQL. To use it,
+first register a new handler service with your database credentials:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # config/services.yaml
+ services:
+ # ...
+
+ Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler:
+ arguments:
+ - '%env(DATABASE_URL)%'
+
+ # you can also use PDO configuration, but requires passing two arguments
+ # - 'mysql:dbname=mydatabase; host=myhost; port=myport'
+ # - { db_username: myuser, db_password: mypassword }
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+ env(DATABASE_URL)
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ // config/services.php
+ use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
+
+ $storageDefinition = $container->autowire(PdoSessionHandler::class)
+ ->setArguments([
+ '%env(DATABASE_URL)%',
+ // you can also use PDO configuration, but requires passing two arguments:
+ // 'mysql:dbname=mydatabase; host=myhost; port=myport',
+ // ['db_username' => 'myuser', 'db_password' => 'mypassword'],
+ ])
+ ;
+
+Next, use the :ref:`handler_id `
+configuration option to tell Symfony to use this service as the session handler:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # config/packages/framework.yaml
+ framework:
+ session:
+ # ...
+ handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ // config/packages/framework.php
+ use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
+
+ // ...
+ $container->loadFromExtension('framework', [
+ // ...
+ 'session' => [
+ 'handler_id' => PdoSessionHandler::class,
+ ],
+ ]);
+
+Configuring the Session Table and Column Names
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The table used to store sessions is called ``sessions`` by default and defines
+certain column names. You can configure these values with the second argument
+passed to the ``PdoSessionHandler`` service:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # config/services.yaml
+ services:
+ # ...
+
+ Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler:
+ arguments:
+ - '%env(DATABASE_URL)%'
+ - { db_table: 'customer_session', db_id_col: 'guid' }
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+ env(DATABASE_URL)
+
+ customer_session
+ guid
+
+
+
+
+
+ .. code-block:: php
+
+ // config/services.php
+ use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
+ // ...
+
+ $container->autowire(PdoSessionHandler::class)
+ ->setArguments([
+ '%env(DATABASE_URL)%',
+ ['db_table' => 'customer_session', 'db_id_col' => 'guid'],
+ ])
+ ;
+
+These are parameters that you can configure:
+
+``db_table`` (default ``sessions``):
+ The name of the session table in your database;
+
+``db_username``: (default: ``''``)
+ The username used to connect when using the PDO configuration (when using
+ the connection based on the ``DATABASE_URL`` env var, it overrides the
+ username defined in the env var).
+
+``db_password``: (default: ``''``)
+ The password used to connect when using the PDO configuration (when using
+ the connection based on the ``DATABASE_URL`` env var, it overrides the
+ password defined in the env var).
+
+``db_id_col`` (default ``sess_id``):
+ The name of the column where to store the session ID (column type: ``VARCHAR(128)``);
+
+``db_data_col`` (default ``sess_data``):
+ The name of the column where to store the session data (column type: ``BLOB``);
+
+``db_time_col`` (default ``sess_time``):
+ The name of the column where to store the session creation timestamp (column type: ``INTEGER``);
+
+``db_lifetime_col`` (default ``sess_lifetime``):
+ The name of the column where to store the session lifetime (column type: ``INTEGER``);
+
+``db_connection_options`` (default: ``[]``)
+ An array of driver-specific connection options;
+
+``lock_mode`` (default: ``LOCK_TRANSACTIONAL``)
+ The strategy for locking the database to avoid *race conditions*. Possible
+ values are ``LOCK_NONE`` (no locking), ``LOCK_ADVISORY`` (application-level
+ locking) and ``LOCK_TRANSACTIONAL`` (row-level locking).
+
+Preparing the Database to Store Sessions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Before storing sessions in the database, you must create the table that stores
+the information. The session handler provides a method called
+:method:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\PdoSessionHandler::createTable`
+to set up this table for you according to the database engine used::
+
+ try {
+ $sessionHandlerService->createTable();
+ } catch (\PDOException $exception) {
+ // the table could not be created for some reason
+ }
+
+If you prefer to set up the table yourself, it's recommended to generate an
+empty database migration with the following command:
+
+.. code-block:: terminal
+
+ $ php bin/console doctrine:migrations:generate
+
+Then, find the appropriate SQL for your database below, add it to the migration
+file and run the migration with the following command:
+
+.. code-block:: terminal
+
+ $ php bin/console doctrine:migrations:migrate
+
+MySQL
+.....
+
+.. code-block:: sql
+
+ CREATE TABLE `sessions` (
+ `sess_id` VARBINARY(128) NOT NULL PRIMARY KEY,
+ `sess_data` BLOB NOT NULL,
+ `sess_lifetime` MEDIUMINT NOT NULL,
+ `sess_time` INTEGER UNSIGNED NOT NULL
+ ) COLLATE utf8mb4_bin, ENGINE = InnoDB;
+
+.. note::
+
+ A ``BLOB`` column type (which is the one used by default by ``createTable()``)
+ stores up to 64 kb. If the user session data exceeds this, an exception may
+ be thrown or their session will be silently reset. Consider using a ``MEDIUMBLOB``
+ if you need more space.
+
+PostgreSQL
+..........
+
+.. code-block:: sql
+
+ CREATE TABLE sessions (
+ sess_id VARCHAR(128) NOT NULL PRIMARY KEY,
+ sess_data BYTEA NOT NULL,
+ sess_lifetime INTEGER NOT NULL,
+ sess_time INTEGER NOT NULL
+ );
+
+Microsoft SQL Server
+....................
+
+.. code-block:: sql
+
+ CREATE TABLE sessions (
+ sess_id VARCHAR(128) NOT NULL PRIMARY KEY,
+ sess_data VARBINARY(MAX) NOT NULL,
+ sess_lifetime INTEGER NOT NULL,
+ sess_time INTEGER NOT NULL
+ );
+
+Store Sessions in a NoSQL Database (MongoDB)
+--------------------------------------------
+
+Symfony includes a :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MongoDbSessionHandler`
+to store sessions in the MongoDB NoSQL database. First, make sure to have a
+working MongoDB connection in your Symfony application as explained in the
+`DoctrineMongoDBBundle configuration`_ article.
+
+Then, register a new handler service for ``MongoDbSessionHandler`` and pass it
+the MongoDB connection as argument:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # config/services.yaml
+ services:
+ # ...
+
+ Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler:
+ arguments:
+ - '@doctrine_mongodb.odm.default_connection'
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+ doctrine_mongodb.odm.default_connection
+
+
+
+
+ .. code-block:: php
+
+ // config/services.php
+ use Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler;
+
+ $storageDefinition = $container->autowire(MongoDbSessionHandler::class)
+ ->setArguments([
+ new Reference('doctrine_mongodb.odm.default_connection'),
+ ])
+ ;
+
+Next, use the :ref:`handler_id `
+configuration option to tell Symfony to use this service as the session handler:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # config/packages/framework.yaml
+ framework:
+ session:
+ # ...
+ handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+ .. code-block:: php
+
+ // config/packages/framework.php
+ use Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler;
+
+ // ...
+ $container->loadFromExtension('framework', [
+ // ...
+ 'session' => [
+ 'handler_id' => MongoDbSessionHandler::class,
+ ],
+ ]);
+
+.. note::
+
+ MongoDB ODM 1.x only works with the legacy driver, which is no longer
+ supported by the Symfony session class. Install the ``alcaeus/mongo-php-adapter``
+ package to retrieve the underlying ``\MongoDB\Client`` object or upgrade to
+ MongoDB ODM 2.0.
+
+That's all! Symfony will now use your MongoDB server to read and write the
+session data. You do not need to do anything to initialize your session
+collection. However, you may want to add an index to improve garbage collection
+performance. Run this from the `MongoDB shell`_:
+
+.. code-block:: javascript
+
+ use session_db
+ db.session.ensureIndex( { "expires_at": 1 }, { expireAfterSeconds: 0 } )
+
+Configuring the Session Field Names
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The collection used to store sessions defines certain field names. You can
+configure these values with the second argument passed to the
+``MongoDbSessionHandler`` service:
+
+.. configuration-block::
+
+ .. code-block:: yaml
+
+ # config/services.yaml
+ services:
+ # ...
+
+ Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler:
+ arguments:
+ - '@doctrine_mongodb.odm.default_connection'
+ - { id_field: '_guid', `expiry_field`: `eol` }
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+ doctrine_mongodb.odm.default_connection
+
+ _guid
+ eol
+
+
+
+
+
+ .. code-block:: php
+
+ // config/services.php
+ use Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler;
+ // ...
+
+ $container->autowire(MongoDbSessionHandler::class)
+ ->setArguments([
+ '...',
+ ['id_field' => '_guid', 'expiry_field' => 'eol'],
+ ])
+ ;
+
+These are parameters that you can configure:
+
+``id_field`` (default ``_id``):
+ The name of the field where to store the session ID;
+
+``data_field`` (default ``data``):
+ The name of the field where to store the session data;
+
+``time_field`` (default ``time``):
+ The name of the field where to store the session creation timestamp;
+
+``expiry_field`` (default ``expires_at``):
+ The name of the field where to store the session lifetime.
+
+.. _`phpredis extension`: https://github.com/phpredis/phpredis
+.. _`DoctrineMongoDBBundle configuration`: https://symfony.com/doc/master/bundles/DoctrineMongoDBBundle/config.html
+.. _`MongoDB shell`: https://docs.mongodb.com/manual/mongo/