Cache

Using a cache is a great way of making your application run quicker. The Symfony cache component ships with many adapters to different storages. Every adapter is developed for high performance.

キャッシュの使用は、アプリケーションの実行を高速化する優れた方法です。 Symfony キャッシュ コンポーネントには、さまざまなストレージへの多くのアダプターが同梱されています。すべてのアダプターは高性能のために開発されています。

The following example shows a typical usage of the cache:

次の例は、キャッシュの一般的な使用法を示しています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use Symfony\Contracts\Cache\ItemInterface;

// The callable will only be executed on a cache miss.
$value = $pool->get('my_cache_key', function (ItemInterface $item) {
    $item->expiresAfter(3600);

    // ... do some HTTP request or heavy computations
    $computedValue = 'foobar';

    return $computedValue;
});

echo $value; // 'foobar'

// ... and to remove the cache key
$pool->delete('my_cache_key');

Symfony supports Cache Contracts and PSR-6/16 interfaces. You can read more about these at the component documentation.

Symfony は、キャッシュ コントラクトと PSR-6/16 インターフェースをサポートしています。これらの詳細については、コンポーネントのドキュメントを参照してください。

Configuring Cache with FrameworkBundle

When configuring the cache component there are a few concepts you should know of:

キャッシュ コンポーネントを構成するときに知っておくべき概念がいくつかあります。
Pool
This is a service that you will interact with. Each pool will always have its own namespace and cache items. There is never a conflict between pools.
これは、対話するサービスです。各プールには、常に独自の名前空間とキャッシュ アイテムがあります。プール間で競合が発生することはありません。
Adapter
An adapter is a template that you use to create pools.
アダプターは、プールの作成に使用するテンプレートです。
Provider
A provider is a service that some adapters use to connect to the storage. Redis and Memcached are examples of such adapters. If a DSN is used as the provider then a service is automatically created.
プロバイダーは、一部のアダプターがストレージに接続するために使用するサービスです。Redis と Memcached は、このようなアダプターの例です。 DSN がプロバイダーとして使用される場合、サービスが自動的に作成されます。

There are two pools that are always enabled by default. They are cache.app and cache.system. The system cache is used for things like annotations, serializer, and validation. The cache.app can be used in your code. You can configure which adapter (template) they use by using the app and system key like:

デフォルトで常に有効になっているプールが 2 つあります。これらは、cache.app と cache.system です。システム キャッシュは、注釈、シリアライザー、検証などに使用されます。コードで cache.app を使用できます。次のようなアプリとシステムキーを使用して、使用するアダプター (テンプレート) を構成できます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
# config/packages/cache.yaml
framework:
    cache:
        app: cache.adapter.filesystem
        system: cache.adapter.system

Tip

ヒント

While it is possible to reconfigure the system cache, it's recommended to keep the default configuration applied to it by Symfony.

システムキャッシュを再構成することは可能ですが、Symfony によって適用されるデフォルト構成を維持することをお勧めします。

The Cache component comes with a series of adapters pre-configured:

キャッシュ コンポーネントには、一連のアダプターがあらかじめ構成されています。

Some of these adapters could be configured via shortcuts. Using these shortcuts will create pools with service IDs that follow the pattern cache.[type].

これらのアダプターの一部は、ショートカットを介して構成できます。これらのショートカットを使用すると、パターン cache.[type] に従うサービス ID を持つプールが作成されます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
# config/packages/cache.yaml
framework:
    cache:
        directory: '%kernel.cache_dir%/pools' # Only used with cache.adapter.filesystem

        # service: cache.psr6
        default_psr6_provider: 'app.my_psr6_service'
        # service: cache.redis
        default_redis_provider: 'redis://localhost'
        # service: cache.memcached
        default_memcached_provider: 'memcached://localhost'
        # service: cache.pdo
        default_pdo_provider: 'doctrine.dbal.default_connection'

Creating Custom (Namespaced) Pools

You can also create more customized pools:

さらにカスタマイズされたプールを作成することもできます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    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
26
27
28
29
30
31
# config/packages/cache.yaml
framework:
    cache:
        default_memcached_provider: 'memcached://localhost'

        pools:
            # creates a "custom_thing.cache" service
            # autowireable via "CacheInterface $customThingCache"
            # uses the "app" cache configuration
            custom_thing.cache:
                adapter: cache.app

            # creates a "my_cache_pool" service
            # autowireable via "CacheInterface $myCachePool"
            my_cache_pool:
                adapter: cache.adapter.filesystem

            # uses the default_memcached_provider from above
            acme.cache:
                adapter: cache.adapter.memcached

            # control adapter's configuration
            foobar.cache:
                adapter: cache.adapter.memcached
                provider: 'memcached://user:password@example.com'

            # uses the "foobar.cache" pool as its backend but controls
            # the lifetime and (like all pools) has a separate cache namespace
            short_cache:
                adapter: foobar.cache
                default_lifetime: 60

Each pool manages a set of independent cache keys: keys from different pools never collide, even if they share the same backend. This is achieved by prefixing keys with a namespace that's generated by hashing the name of the pool, the name of the cache adapter class and a configurable seed that defaults to the project directory and compiled container class.

各プールは、独立したキャッシュ キーのセットを管理します。異なるプールのキーが同じバックエンドを共有していても、決して衝突することはありません。これは、プールの名前、キャッシュ アダプター クラスの名前、およびプロジェクト ディレクトリとコンパイル済みコンテナー クラスを既定値とする構成可能なシードのハッシュによって生成される名前空間をキーにプレフィックスとして付けることによって実現されます。

Each custom pool becomes a service whose service ID is the name of the pool (e.g. custom_thing.cache). An autowiring alias is also created for each pool using the camel case version of its name - e.g. custom_thing.cache can be injected automatically by naming the argument $customThingCache and type-hinting it with either CacheInterface or Psr\Cache\CacheItemPoolInterface:

各カスタム プールは、サービス ID がプールの名前 (例: custom_thing.cache) であるサービスになります。キャメルケースバージョンの名前を使用して、プールごとに自動配線エイリアスも作成されます。 custom_thing.cache は、引数 $customThingCache に名前を付け、それを CacheInterface または Psr\Cache\CacheItemPoolInterface のいずれかで型ヒントすることにより、自動的に注入できます。
1
2
3
4
5
6
7
8
9
10
11
12
13
use Symfony\Contracts\Cache\CacheInterface;

// from a controller method
public function listProducts(CacheInterface $customThingCache)
{
    // ...
}

// in a service
public function __construct(CacheInterface $customThingCache)
{
    // ...
}

Tip

ヒント

If you need the namespace to be interoperable with a third-party app, you can take control over auto-generation by setting the namespace attribute of the cache.pool service tag. For example, you can override the service definition of the adapter:

名前空間をサードパーティ アプリと相互運用できるようにする必要がある場合は、cache.pool サービス タグの名前空間属性を設定することで、自動生成を制御できます。たとえば、アダプタのサービス定義をオーバーライドできます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
# config/services.yaml
services:
    # ...

    app.cache.adapter.redis:
        parent: 'cache.adapter.redis'
        tags:
            - { name: 'cache.pool', namespace: 'my_custom_namespace' }

Custom Provider Options

Some providers have specific options that can be configured. The RedisAdapter allows you to create providers with the options timeout, retry_interval. etc. To use these options with non-default values you need to create your own \Redis provider and use that when configuring the pool.

一部のプロバイダーには、構成可能な特定のオプションがあります。 RedisAdapter を使用すると、タイムアウト、retry_interval オプションを使用してプロバイダーを作成できます。これらのオプションをデフォルト以外の値で使用するには、独自の \Redis プロバイダーを作成し、プールの構成時にそれを使用する必要があります。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# config/packages/cache.yaml
framework:
    cache:
        pools:
            cache.my_redis:
                adapter: cache.adapter.redis
                provider: app.my_custom_redis_provider

services:
    app.my_custom_redis_provider:
        class: \Redis
        factory: ['Symfony\Component\Cache\Adapter\RedisAdapter', 'createConnection']
        arguments:
            - 'redis://localhost'
            - { retry_interval: 2, timeout: 10 }

Creating a Cache Chain

Different cache adapters have different strengths and weaknesses. Some might be really quick but optimized to store small items and some may be able to contain a lot of data but are quite slow. To get the best of both worlds you may use a chain of adapters.

キャッシュ アダプターが異なれば、長所と短所も異なります。非常に高速ですが、小さなアイテムを保存するように最適化されているものもあれば、大量のデータを格納できるが非常に遅いものもあります。両方の世界を最大限に活用するには、一連のアダプターを使用できます。

A cache chain combines several cache pools into a single one. When storing an item in a cache chain, Symfony stores it in all pools sequentially. When retrieving an item, Symfony tries to get it from the first pool. If it's not found, it tries the next pools until the item is found or an exception is thrown. Because of this behavior, it's recommended to define the adapters in the chain in order from fastest to slowest.

キャッシュ チェーンは、複数のキャッシュ プールを 1 つに結合します。アイテムをキャッシュ チェーンに格納する場合、Symfony はそれをすべてのプールに順番に格納します。アイテムを取得するとき、Symfony は最初のプールから取得しようとします。見つからない場合は、項目が見つかるか例外がスローされるまで、次のプールを試行します。この動作のため、チェーン内のアダプターを最速のものから順に定義することをお勧めします。

If an error happens when storing an item in a pool, Symfony stores it in the other pools and no exception is thrown. Later, when the item is retrieved, Symfony stores the item automatically in all the missing pools.

プールに項目を保存するときにエラーが発生した場合、Symfony はそれを他のプールに保存し、例外はスローされません。後でアイテムが取得されると、Symfony は不足しているすべてのプールにアイテムを自動的に保存します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
# config/packages/cache.yaml
framework:
    cache:
        pools:
            my_cache_pool:
                default_lifetime: 31536000  # One year
                adapters:
                  - cache.adapter.array
                  - cache.adapter.apcu
                  - {name: cache.adapter.redis, provider: 'redis://user:password@example.com'}

Using Cache Tags

In applications with many cache keys it could be useful to organize the data stored to be able to invalidate the cache more efficiently. One way to achieve that is to use cache tags. One or more tags could be added to the cache item. All items with the same key could be invalidated with one function call:

多くのキャッシュ キーを持つアプリケーションでは、格納されたデータを整理して、キャッシュをより効率的に無効にできると便利です。これを実現する 1 つの方法は、キャッシュ タグを使用することです。 1 つまたは複数のタグをキャッシュ アイテムに追加できます。同じキーを持つすべてのアイテムは、1 つの関数呼び出しで無効にすることができます。
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
use Symfony\Contracts\Cache\ItemInterface;
use Symfony\Contracts\Cache\TagAwareCacheInterface;

class SomeClass
{
    private $myCachePool;

    // using autowiring to inject the cache pool
    public function __construct(TagAwareCacheInterface $myCachePool)
    {
        $this->myCachePool = $myCachePool;
    }

    public function someMethod()
    {
        $value0 = $this->myCachePool->get('item_0', function (ItemInterface $item) {
            $item->tag(['foo', 'bar']);

            return 'debug';
        });

        $value1 = $this->myCachePool->get('item_1', function (ItemInterface $item) {
            $item->tag('foo');

            return 'debug';
        });

        // Remove all cache keys tagged with "bar"
        $this->myCachePool->invalidateTags(['bar']);
    }
}

The cache adapter needs to implement TagAwareCacheInterface to enable this feature. This could be added by using the following configuration.

この機能を有効にするには、キャッシュ アダプターに TagAwareCacheInterface を実装する必要があります。これは、次の構成を使用して追加できます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
# config/packages/cache.yaml
framework:
    cache:
        pools:
            my_cache_pool:
                adapter: cache.adapter.redis
                tags: true

Tags are stored in the same pool by default. This is good in most scenarios. But sometimes it might be better to store the tags in a different pool. That could be achieved by specifying the adapter.

タグはデフォルトで同じプールに保存されます。これは、ほとんどのシナリオで適切です。ただし、タグを別のプールに保存した方がよい場合もあります。これは、アダプターを指定することで解決できます。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
# config/packages/cache.yaml
framework:
    cache:
        pools:
            my_cache_pool:
                adapter: cache.adapter.redis
                tags: tag_pool
            tag_pool:
                adapter: cache.adapter.apcu

Note

ノート

The interface TagAwareCacheInterface is autowired to the cache.app service.

インターフェース TagAwareCacheInterface は、cache.app サービスに自動配線されます。

Clearing the Cache

To clear the cache you can use the bin/console cache:pool:clear [pool] command. That will remove all the entries from your storage and you will have to recalculate all the values. You can also group your pools into "cache clearers". There are 3 cache clearers by default:

キャッシュをクリアするには、bin/console cache:pool:clear [pool] コマンドを使用できます。これにより、ストレージからすべてのエントリが削除され、すべての値を再計算する必要があります。プールを「キャッシュ クリアラー」にグループ化することもできます。デフォルトでは 3 つのキャッシュクリアラーがあります。
  • cache.global_clearer
    cache.global_clearer
  • cache.system_clearer
    cache.system_clearer
  • cache.app_clearer
    cache.app_clearer

The global clearer clears all the cache items in every pool. The system cache clearer is used in the bin/console cache:clear command. The app clearer is the default clearer.

グローバル クリアラーは、すべてのプール内のすべてのキャッシュ アイテムをクリアします。 bin/console cache:clear コマンドでは、システム キャッシュ クリアエリスが使用されます。アプリのクリアラーはデフォルトのクリアラーです。

To see all available cache pools:

使用可能なすべてのキャッシュ プールを表示するには:
1
$ php bin/console cache:pool:list

Clear one pool:

1 つのプールをクリアします。
1
$ php bin/console cache:pool:clear my_cache_pool

Clear all custom pools:

すべてのカスタム プールをクリアします。
1
$ php bin/console cache:pool:clear cache.app_clearer

Clear all caches everywhere:

どこでもすべてのキャッシュをクリアします。
1
$ php bin/console cache:pool:clear cache.global_clearer

Clear cache by tag(s):

タグでキャッシュをクリア:

6.1

6.1

The cache:pool:invalidate-tags command was introduced in Symfony 6.1.

cache:pool:invalidate-tags コマンドは Symfony 6.1 で導入されました。
1
2
3
4
5
6
7
8
9
10
11
# invalidate tag1 from all taggable pools
$ php bin/console cache:pool:invalidate-tags tag1

# invalidate tag1 & tag2 from all taggable pools
$ php bin/console cache:pool:invalidate-tags tag1 tag2

# invalidate tag1 & tag2 from cache.app pool
$ php bin/console cache:pool:invalidate-tags tag1 tag2 --pool=cache.app

# invalidate tag1 & tag2 from cache1 & cache2 pools
$ php bin/console cache:pool:invalidate-tags tag1 tag2 -p cache1 -p cache2

Encrypting the Cache

To encrypt the cache using libsodium, you can use the SodiumMarshaller.

libsodium を使用してキャッシュを暗号化するには、SodiumMarshaller を使用できます。

First, you need to generate a secure key and add it to your secret store as CACHE_DECRYPTION_KEY:

まず、安全なキーを生成し、CACHE_DECRYPTION_KEY としてシークレットストアに追加する必要があります。
1
$ php -r 'echo base64_encode(sodium_crypto_box_keypair());'

Then, register the SodiumMarshaller service using this key:

次に、このキーを使用して SodiumMarshaller サービスを登録します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
5
6
7
8
9
10
11
# config/packages/cache.yaml

# ...
services:
    Symfony\Component\Cache\Marshaller\SodiumMarshaller:
        decorates: cache.default_marshaller
        arguments:
            - ['%env(base64:CACHE_DECRYPTION_KEY)%']
            # use multiple keys in order to rotate them
            #- ['%env(base64:CACHE_DECRYPTION_KEY)%', '%env(base64:OLD_CACHE_DECRYPTION_KEY)%']
            - '@Symfony\Component\Cache\Marshaller\SodiumMarshaller.inner'

Caution

注意

This will encrypt the values of the cache items, but not the cache keys. Be careful not to leak sensitive data in the keys.

これにより、キャッシュ アイテムの値が暗号化されますが、キャッシュ キーは暗号化されません。キー内の機密データが漏洩しないように注意してください。

When configuring multiple keys, the first key will be used for reading and writing, and the additional key(s) will only be used for reading. Once all cache items encrypted with the old key have expired, you can completely remove OLD_CACHE_DECRYPTION_KEY.

複数のキーを構成する場合、最初のキーは読み取りと書き込みに使用され、追加のキーは読み取りのみに使用されます。古いキーで暗号化されたすべてのキャッシュ アイテムの有効期限が切れたら、OLD_CACHE_DECRYPTION_KEY を完全に削除できます。