Как использовать MongoDbSessionHandler для сохранения сессий в базе данных MongoDB

Хранилище сессий Symfony по умолчанию записывает информацию о сессиях в файлы. Некоторые средние и большие по размеру веб-сайты используют базу данных NoSQL под названием MongoDB для того, чтобы хранить значения сессий, а не файлы, так как базы данных проще использовать и масштабировать в мульти-серверном окружении.

Symfony имеет встроенное решение для хранилища сессий БД NoSQL под названием MongoDbSessionHandler. MongoDB - это документ из открытых источников, который предоставляет высокую производительность, доступность и автоматическое масштабирование. Эта статья предполагает, что вы уже установили и сконфигурировали сервер MongoDB. Чтобы использовать его, вам просто нужно изменить/добавить некоторые параметры к основному файлу конфигурации:

  • YAML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # 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
    
    services:
        # ...
        mongo_client:
            class: MongoClient
            # если используются имя пользователя и пароль
            arguments: ['mongodb://%mongodb_username%:%mongodb_password%@%mongodb_host%:27017']
            # если имя пользователя и пароль не используются
            arguments: ['mongodb://%mongodb_host%:27017']
        session.handler.mongo:
            class: Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler
            arguments: ['@mongo_client', '%mongo.session.options%']
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    <?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 и gc-max необязательный и имеют значение
                 30 дней в этом примере -->
            <framework:session handler-id="session.handler.mongo"
                cookie-lifetime="2592000"
                gc-maxlifetime="2592000"
            />
        </framework:config>
    
        <services>
            <service id="mongo_client" class="MongoClient">
                <!-- если используются имя пользователя и пароль -->
                <argument>mongodb://%mongodb_username%:%mongodb_password%@%mongodb_host%:27017</argument>
    
                <!-- если имя пользователя и пароль не используются -->
                <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
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    use Symfony\Component\DependencyInjection\Reference;
    use Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler;
    
    $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->register('mongo_client', \MongoClient::class)
        ->setArguments(array(
            // если используются имя пользователя и пароль
            array('mongodb://%mongodb_username%:%mongodb_password%@%mongodb_host%:27017'),
            // если имя пользователя и пароль не используются
            array('mongodb://%mongodb_host%:27017'),
        ));
    
    $container->register('session.handler.mongo', MongoDbSessionHandler::class)
        ->setArguments(array(
            new Reference('mongo_client'),
            '%mongo.session.options%',
        ));
    

Параметры, используемые выше, должны быть определены где-то в вашем пнриложении, часто - в вашей главной конфигурации параметров:

  • YAML
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # app/config/parameters.yml
    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
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <?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">
    
        <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>
    </container>
    
  • PHP
    1
    2
    3
    4
    5
    6
    7
    8
    9
    use Symfony\Component\DependencyInjection\Reference;
    
    $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');
    

Установка сбора MongoDB

Так как MongoDB использует динамические схемы сбора, вам не нужно ничего делать для того, чтобы инициализировать сбор сессии. Однако, вам может захотеться добавить оглавление, чтобы улучшить производительность сбора мусора. Из оболочки MongoDB:

1
2
use session_db
db.session.ensureIndex( { "expires_at": 1 }, { expireAfterSeconds: 0 } )

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.