My requirements:
Use the database for all caching in the app
Cache should reuse the connection I already have in the Symfony app via Doctrine
It took longer than I expected to figure that out. Symfony’s Cache documentation was confusing to me. Adapters? Providers?
Direct Solution
If you don’t have much time, here’s what you need to do:
config/packages/config.yaml
1framework:2 cache:3 app: cache.adapter.doctrine_dbal
This tells Symfony to use the Doctrine Adapter to create the cache pool. It uses the default Doctrine connection (I verified that it does not create a separate connection for this)
Explanation
A pool has methods like get()
to get/set cache. To create a pool, you need an adapter. It’s kind of like the factory, but it needs some “data” to create the pool. See the source code of the DoctrineDbalAdapter. It needs a connection or a connection string to create the pool, which makes sense. A provider provides that “data”.
Let’s find out more. Run the following:
1bin/console config:dump framework cache
You get something like this:
1cache: 2 prefix_seed: ... 3 4 # App related cache pools configuration. 5 app: cache.adapter.filesystem 6 7 # System related cache pools configuration. 8 system: cache.adapter.system 9 directory: '%kernel.cache_dir%/pools/app'10 default_psr6_provider: ~11 default_redis_provider: 'redis://localhost'12 default_valkey_provider: 'valkey://localhost'13 default_memcached_provider: 'memcached://localhost'14 default_doctrine_dbal_provider: database_connection15 default_pdo_provider: null
You can understand that the app
cache pool is set up to use the cache.adapter.filesystem
adapter. When we change it to cache.adapter.doctrine_dbal
, it then uses the service database_connection
as the provider.
1bin/console debug:container database_connection
You find out that database_connection
is an alias for the Doctrine\DBAL\Connection
class, which has the default database connection.
So, by default, this default connection is injected into DoctrineDbalAdapter to create the connection pool. We finally have a cache pool that uses our app’s database connection.
Bonus point: I usually prefer to have migrations nicely located in the migrations folder instead of doing runtime table creation. So, here’s the schema for PGSQL with default table and column names:
1CREATE TABLE cache_items (2 item_id varchar(255) NOT NULL PRIMARY KEY,3 item_data bytea NOT NULL,4 item_lifetime int4,5 item_time int4 NOT NULL6);
Hopefully, this saves some time!
Comments