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 a database instead to make sessions work across different servers.

symfony はデフォルトでセッションをファイルに保存します。アプリケーションが複数のサーバーによって提供されている場合は、代わりにデータベースを使用して、異なるサーバー間でセッションを機能させる必要があります。

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.

Symfony はあらゆる種類のデータベース (リレーショナル、NoSQL、およびキー値) にセッションを保存できますが、最高のパフォーマンスを得るには Redis のようなキー値データベースをお勧めします。

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.

このセクションでは、完全に機能する Redis サーバーがあり、phpredis 拡張機能もインストールおよび構成されていることを前提としています。

You have two different options to use Redis to store sessions:

Redis を使用してセッションを保存するには、2 つの異なるオプションがあります。

(1) The first PHP-based option is to configure Redis session handler directly in the server php.ini file:

(1) 最初の PHP ベースのオプションは、Redis セッション ハンドラーをサーバーの php.ini ファイルで直接構成することです。
1
2
3
; php.ini
session.save_handler = redis
session.save_path = "tcp://192.168.0.178:6379?auth=REDIS_PASSWORD"
  1. The second Symfony-based option is to configure Redis sessions as follows.
    2 つ目の Symfony ベースのオプションは、次のように Redis セッションを構成することです。

First, define a Symfony service for the connection to the Redis server:

最初に、Redis サーバーへの接続用の Symfony サービスを定義します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# config/services.yaml
services:
    # ...
    Redis:
        # you can also use \RedisArray, \RedisCluster or \Predis\Client classes
        class: Redis
        calls:
            - connect:
                - '%env(REDIS_HOST)%'
                - '%env(int:REDIS_PORT)%'

            # uncomment the following if your Redis server requires a password
            # - auth:
            #     - '%env(REDIS_PASSWORD)%'
            
            # uncomment the following if your Redis server requires a user and a password (when user is not default)
            # - auth:
            #     - ['%env(REDIS_USER)%','%env(REDIS_PASSWORD)%']

Now pass this \Redis connection as an argument of the service associated to the RedisSessionHandler. This argument can also be a \RedisArray, \RedisCluster, \Predis\Client, and RedisProxy:

この \Redis 接続を、RedisSessionHandler に関連付けられたサービスの引数として渡します。この引数は、\RedisArray、\RedisCluster、\Predis\Client、および RedisProxy にすることもできます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
# config/services.yaml
services:
    # ...
    Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler:
        arguments:
            - '@Redis'
            # you can optionally pass an array of options. The only options are 'prefix' and 'ttl',
            # which define the prefix to use for the keys to avoid collision on the Redis server
            # and the expiration time for any given entry (in seconds), defaults are 'sf_s' and null:
            # - { 'prefix': 'my_prefix', 'ttl': 600 }

Next, use the handler_id configuration option to tell Symfony to use this service as the session handler:

次に、handler_idconfiguration オプションを使用して、Symfony にこのサービスをセッションハンドラーとして使用するように指示します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
# config/packages/framework.yaml
framework:
    # ...
    session:
        handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler

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.

それで全部です! symfony は Redis サーバーを使用してセッションデータを読み書きします。このソリューションの主な欠点は、Redis がセッションロックを実行しないため、セッションにアクセスするときに競合状態に直面する可能性があることです。たとえば、2 つのリクエストが並行して行われ、最初のリクエストだけが CSRF トークンをセッションに保存したため、「Invalid CSRF token」エラーが表示される場合があります。

See also

こちらもご覧ください

If you use Memcached instead of Redis, follow a similar approach but replace RedisSessionHandler by MemcachedSessionHandler.

Redis の代わりに Memcached を使用する場合は、同様のアプローチに従いますが、RedisSessionHandler を MemcachedSessionHandler に置き換えます。

Store Sessions in a Relational Database (MariaDB, MySQL, PostgreSQL)

Symfony includes a PdoSessionHandler to store sessions in relational databases like MariaDB, MySQL and PostgreSQL. To use it, first register a new handler service with your database credentials:

Symfony には、MariaDB、MySQL、PostgreSQL などのリレーショナル データベースにセッションを保存するための PdoSessionHandler が含まれています。これを使用するには、まず新しいハンドラー サービスをデータベース資格情報で登録します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
# 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 }

Tip

ヒント

When using MySQL as the database, the DSN defined in DATABASE_URL can contain the charset and unix_socket options as query string parameters.

MySQL をデータベースとして使用する場合、DATABASE_URL で定義された DSN には、クエリ文字列パラメーターとして charset および unix_socket オプションを含めることができます。

Next, use the handler_id configuration option to tell Symfony to use this service as the session handler:

次に、handler_idconfiguration オプションを使用して、Symfony にこのサービスをセッションハンドラーとして使用するように指示します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
# config/packages/framework.yaml
framework:
    session:
        # ...
        handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler

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:

セッションを格納するために使用されるテーブルは、デフォルトでセッションと呼ばれ、特定の列名を定義します。これらの値は、PdoSessionHandler サービスに渡される 2 番目の引数で構成できます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
# config/services.yaml
services:
    # ...

    Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler:
        arguments:
            - '%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).
PDO 構成を使用するときに接続に使用されるユーザー名 (DATABASE_URL 環境変数に基づく接続を使用する場合、環境変数で定義されたユーザー名をオーバーライドします)。
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).
PDO 構成を使用するときに接続に使用されるパスワード (DATABASE_URL 環境変数に基づく接続を使用する場合、環境変数で定義されたパスワードをオーバーライドします)。
db_id_col (default sess_id):
The name of the column where to store the session ID (column type: VARCHAR(128));
セッション ID を格納する列の名前 (列の型: VARCHAR(128));
db_data_col (default sess_data):
The name of the column where to store the session data (column type: BLOB);
セッション データを格納する列の名前 (列の型: BLOB)。
db_time_col (default sess_time):
The name of the column where to store the session creation timestamp (column type: INTEGER);
セッション作成のタイムスタンプを格納する列の名前 (列の型: INTEGER)。
db_lifetime_col (default sess_lifetime):
The name of the column where to store the session lifetime (column type: INTEGER);
セッションの有効期間を格納する列の名前 (列の型: 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).
競合状態を回避するためにデータベースをロックするための戦略。可能な値は、LOCK_NONE (ロックなし)、LOCK_ADVISORY (アプリケーションレベルのロック)、および LOCK_TRANSACTIONAL (行レベルのロック) です。

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 createTable() to set up this table for you according to the database engine used:

セッションをデータベースに保存する前に、情報を保存するテーブルを作成する必要があります。セッション ハンドラーには、使用するデータベース エンジンに応じてこのテーブルをセットアップするための createTable() というメソッドが用意されています。
1
2
3
4
5
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:

自分でテーブルをセットアップする場合は、次のコマンドを使用して空のデータベース マイグレーションを生成することをお勧めします。
1
$ 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:

次に、以下でデータベースに適した SQL を見つけて、それを移行ファイルに追加し、次のコマンドで移行を実行します。
1
$ php bin/console doctrine:migrations:migrate

MariaDB/MySQL

1
2
3
4
5
6
7
CREATE TABLE `sessions` (
    `sess_id` VARBINARY(128) NOT NULL PRIMARY KEY,
    `sess_data` BLOB NOT NULL,
    `sess_lifetime` INTEGER UNSIGNED NOT NULL,
    `sess_time` INTEGER UNSIGNED NOT NULL,
    INDEX `sessions_sess_lifetime_idx` (`sess_lifetime`)
) 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.

BLOB 列タイプ (createTable() によってデフォルトで使用されるタイプ) は、最大 64 kb を格納します。ユーザー セッション データがこれを超えると、例外がスローされるか、セッションがサイレントにリセットされます。さらにスペースが必要な場合は、MEDIUMBLOB の使用を検討してください。

PostgreSQL

1
2
3
4
5
6
7
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
);
CREATE INDEX sessions_sess_lifetime_idx ON sessions (sess_lifetime);

Microsoft SQL Server

1
2
3
4
5
6
7
CREATE TABLE sessions (
    sess_id VARCHAR(128) NOT NULL PRIMARY KEY,
    sess_data NVARCHAR(MAX) NOT NULL,
    sess_lifetime INTEGER NOT NULL,
    sess_time INTEGER NOT NULL,
    INDEX sessions_sess_lifetime_idx (sess_lifetime)
);

Store Sessions in a NoSQL Database (MongoDB)

Symfony includes a 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.

Symfony には、MongoDB NoSQL データベースにセッションを保存するための MongoDbSessionHandler が含まれています。まず、DoctrineMongoDBBundle 構成記事で説明されているように、Symfony アプリケーションで MongoDB 接続が機能していることを確認してください。

Then, register a new handler service for MongoDbSessionHandler and pass it the MongoDB connection as argument:

次に、MongoDbSessionHandler の新しいハンドラー サービスを登録し、MongoDB 接続を引数として渡します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
# config/services.yaml
services:
    # ...

    Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler:
        arguments:
            - '@doctrine_mongodb.odm.default_connection'

Next, use the handler_id configuration option to tell Symfony to use this service as the session handler:

次に、handler_idconfiguration オプションを使用して、Symfony にこのサービスをセッションハンドラーとして使用するように指示します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
# config/packages/framework.yaml
framework:
    session:
        # ...
        handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler

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.

MongoDB ODM 1.x は、Symfony セッション クラスでサポートされなくなったレガシー ドライバーでのみ動作します。 alcaeus/mongo-php-adapter パッケージをインストールして、基礎となる \MongoDB\Client オブジェクトを取得するか、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:

それで全部です!これで、symfony は MongoDB サーバーを使用してセッション データを読み書きします。セッションコレクションを初期化するために何もする必要はありません。ただし、ガベージ コレクションのパフォーマンスを向上させるために、インデックスを追加することをお勧めします。これを MongoDB シェルから実行します。
1
2
use session_db
db.session.createIndex( { "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:

セッションの保存に使用されるコレクションは、特定のフィールド名を定義します。これらの値は、MongoDbSessionHandler サービスに渡される 2 番目の引数で構成できます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
# config/services.yaml
services:
    # ...

    Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler:
        arguments:
            - '@doctrine_mongodb.odm.default_connection'
            - { 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;
セッション 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.
セッションの有効期間を格納するフィールドの名前。