@@ -91,30 +91,61 @@ Creating Sub-Namespaces
9191
9292 Cache sub-namespaces were introduced in Symfony 7.3.
9393
94- All cache adapters provided by the component implement the
95- :class: `Symfony\\ Contracts\\ Cache\\ NamespacedPoolInterface ` to provide the
96- :method: `Symfony\\ Contracts\\ Cache\\ NamespacedPoolInterface::withSubNamespace ` method.
97- This method allows namespacing cached items by transparently prefixing their keys::
94+ Sometimes you need to create context-dependent variations of data that should be
95+ cached. For example, the data used to render a dashboard page may be expensive
96+ to generate and unique per user, so you can't cache the same data for everyone.
9897
99- $subCache = $cache->withSubNamespace('foo');
98+ In such cases, Symfony allows you to create different cache contexts using
99+ namespaces. A cache namespace is an arbitrary string that identifies a set of
100+ related cache items. All cache adapters provided by the component implement the
101+ :class: `Symfony\\ Contracts\\ Cache\\ NamespacedPoolInterface `, which provides the
102+ :method: `Symfony\\ Contracts\\ Cache\\ NamespacedPoolInterface::withSubNamespace `
103+ method.
100104
101- $subCache->get('my_cache_key', function (ItemInterface $item): string {
105+ This method allows you to namespace cached items by transparently prefixing their keys::
106+
107+ $userCache = $cache->withSubNamespace(sprintf('user-%d', $user->getId()));
108+
109+ $userCache->get('dashboard_data', function (ItemInterface $item): string {
102110 $item->expiresAfter(3600);
103111
104112 return '...';
105113 });
106114
107- In this example, the cache item will use the ``my_cache_key `` key, but it will be
108- stored internally under the `` foo `` namespace . This is handled transparently for
109- you , so you **don' t ** need to manually prefix keys like ``foo.my_cache_key ``.
115+ In this example, the cache item uses the ``dashboard_data `` key, but it will be
116+ stored internally under a namespace based on the current user ID . This is handled
117+ automatically , so you **don’ t ** need to manually prefix keys like ``user-27.dashboard_data ``.
110118
111- This is useful when using namespace-based cache invalidation to isolate or
112- invalidate a subset of cached data based on some context. Typical examples
113- include namespacing by user ID, locale, or entity ID and hash::
119+ There are no guidelines or restrictions on how to define cache namespaces.
120+ You can make them as granular or as generic as your application requires:
114121
115- $userCache = $cache->withSubNamespace((string) $userId);
116122 $localeCache = $cache->withSubNamespace($request->getLocale());
117- $productCache = $cache->withSubNamespace($productId.'_'.$productChecksum);
123+
124+ $flagCache = $cache->withSubNamespace(
125+ $featureToggle->isEnabled('new_checkout') ? 'checkout-v2' : 'checkout-v1'
126+ );
127+
128+ $channel = $request->attributes->get('_route')?->startsWith('api _') ? 'api' : 'web';
129+ $channelCache = $cache->withSubNamespace($channel);
130+
131+ .. tip ::
132+
133+ You can even combine cache namespaces with :ref: `cache tags <cache-using-cache-tags >`
134+ for more advanced needs.
135+
136+ There is no built-in way to invalidate caches by namespace. Instead, the recommended
137+ approach is to change the namespace itself. For this reason, it's common to include
138+ static or dynamic versioning data in the cache namespace::
139+
140+ // for simple applications, an incrementing static version number may be enough
141+ $userCache = $cache->withSubNamespace(sprintf('v1-user-%d', $user->getId()));
142+
143+ // other applications may use dynamic versioning based on the date (e.g. monthly)
144+ $userCache = $cache->withSubNamespace(sprintf('%s-user-%d', date('Ym'), $user->getId()));
145+
146+ // or even invalidate the cache when the user data changes
147+ $checksum = hash('xxh128', $user->getUpdatedAt()->format(DATE_ATOM));
148+ $userCache = $cache->withSubNamespace(sprintf('user-%d-%s', $user->getId(), $checksum));
118149
119150.. _cache_stampede-prevention :
120151
0 commit comments