Skip to content

Add cookbook article for using MongoDB to store session data #5478

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
54 changes: 54 additions & 0 deletions cookbook/configuration/mongodb_session_storage.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
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`.
MongoDB is an open-source document database that provides high performance,
high availability, and automatic scaling. This article assumes that you have
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor correction: we don't use the so-called "serial comma", so the comma before the and word must be removed. Thanks.

already `installed and configured a MongoDB server`_. To use it, you just
need to change/add some parameters in the main configuration file:

.. configuration-block::

.. code-block:: yaml
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most (all?) Symfony documentation shows how to define things using three different formats (YAML, XML and PHP). I know firsthand how demanding this is (specially for XML) but I'm afraid we have no option here. If you have any troubles with some of the other formats, I'm sure that our doc managers (@wouterj and @xabbuh) will be glad to help you. Thanks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

XML

<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-Instance"
    xmlns:framework="http://symfony.com/schema/dic/symfony"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/symfony
        http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

    <framework:config>
        <!-- ... -->

        <!-- cookie-lifetime and gc-maxlifetime are optional and set to
             30 days in this example -->
        <framework:session handler-id="session.handler.mongo"
            cookie-lifetime="2592000"
            gc-maxlifetime="2592000"
        />
    </framework:config>

    <parameters>
        <parameter key="mongo.session.options" type="collection">
            <!-- your MongoDB database name -->
            <parameter key="database">session_db</parameter>
            <!-- your MongoDB collection name -->
            <parameter key="collection">session</parameter>
        </parameter>
        <!-- your MongoDB server's IP -->
        <parameter key="mongodb_host">1.2.3.4</parameter>
        <parameter key="mongodb_username">my_username</parameter>
        <parameter key="mongodb_password">my_password</parameter>
    </parameters>

    <services>
        <service id="mongo_client" class="MongoClient">
            <!-- if using a username and password -->
            <argument>mongodb://%mongodb_username%:%mongodb_password%@%mongodb_host%:27017</argument>

            <!-- if not using a username and password -->
            <argument>mongodb://%mongodb_host%:27017</argument>
        </service>

        <service id="session.handler.mongo" class="Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler">
            <argument type="service">mongo_client</argument>
            <argument>%mongo.session.options%</argument>
        </service>
</container>

PHP

use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Definition;

$container->loadFromExtension('framework', array(
    'session' => array(
        // ...
        'handler_id'      => 'session.handler.mongo',
        'cookie_lifetime' => 2592000, // optional, it is set to 30 days here
        'gc_maxlifetime'  => 2592000, // optional, it is set to 30 days here
    ),
));

$container->setParameter(

parameters:
    # ...
$container->setParameter('mongo.session.options', array(
    'database'   => 'session_db', // your MongoDB database name
    'collection' => 'session',  // your MongoDB collection name
));
$container->setParameter('mongodb_host', '1.2.3.4'); // your MongoDB server's IP
$container->setParameter('mongodb_username', 'my_username');
$container->setParameter('mongodb_password', 'my_password');

$container->setDefinition('mongo_client', new Definition('MongoClient', array(
    // if using a username and password
    array('mongodb://%mongodb_username%:%mongodb_password%@%mongodb_host%:27017'),
    // if not using a username and password
    array('mongodb://%mongodb_host%:27017'),
)));

$container->setDefinition('session.handler.mongo', new Definition(
    'Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler',
    array(new Reference('mongo_client'), '%mongo.session.options%')
));

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we should configure the parameters in all code examples. Usually one would simply put them in their parameters.yml file and just refers to them in the service configuration. Imho we should simply show the service configurations and add an explanation that these parameters need to be defined somewhere (like you do with other database connections as well).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, however, I do think it would add clarity to show how this is done, so I moved the parameter definitions to a separate section of the article in my latest commit. @wouterj would you please review the XML and PHP sections of the new addition?


# app/config/config.yml
framework:
session:
# ...
handler_id: session.handler.mongo
cookie_lifetime: 2592000 # optional, it is set to 30 days here
gc_maxlifetime: 2592000 # optional, it is set to 30 days here

parameters:
# ...
mongo.session.options:
database: session_db # your MongoDB database name
collection: session # your MongoDB collection name
mongodb_host: 1.2.3.4 # your MongoDB server's IP
mongodb_username: my_username
mongodb_password: my_password

services:
# ...
mongo_client:
class: MongoClient
# if using a username and password
arguments: [mongodb://%mongodb_username%:%mongodb_password%@%mongodb_host%:27017]
# if not using a username and password
arguments: [mongodb://%mongodb_host%:27017]
session.handler.mongo:
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler
arguments: [@mongo_client, %mongo.session.options%]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

% is a reserved first character in older versions of the Yaml spec. Unfortunately, the syntax highlighter used on symfony.com follows this spec and breaks. Can you please wrap it in double quotes, "%mongo.session.options%"?


Setting Up the MongoDB Collection
---------------------------------
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor issue: please leave an empty line after the headline underline. Thanks.

Because MongoDB uses dynamic collection schemas, you do not need to do anything to initialize your
session collection.

.. _installed and configured a MongoDB server: http://docs.mongodb.org/manual/installation/