Information about the Drupal Cache API
Note: If not specified, all of the methods mentioned here belong to \Drupal\Core\Cache\CacheBackendInterface.
The Cache API is used to store data that takes a long time to compute. Caching can either be permanent or valid only for a certain timespan, and the cache can contain any type of data.
To use the Cache API:
Example:
$cid = 'mymodule_example:' . \Drupal::languageManager()->getCurrentLanguage()->getId(); $data = NULL; if ($cache = \Drupal::cache()->get($cid)) { $data = $cache->data; } else { $data = my_module_complicated_calculation(); \Drupal::cache()->set($cid, $data); }
Note the use of $data and $cache->data in the above example. Calls to \Drupal::cache()->get() return a record that contains the information stored by \Drupal::cache()->set() in the data property as well as additional meta information about the cached data. In order to make use of the cached data you can access it via $cache->data.
Cache storage is separated into "bins", each containing various cache items. Each bin can be configured separately; see Configuration.
When you request a cache object, you can specify the bin name in your call to \Drupal::cache(). Alternatively, you can request a bin by getting service "cache.nameofbin" from the container. The default bin is called "default", with service name "cache.default", it is used to store common and frequently used caches.
Other common cache bins are the following:
A module can define a cache bin by defining a service in its modulename.services.yml file as follows (substituting the desired name for "nameofbin"):
cache.nameofbin: class: Drupal\Core\Cache\CacheBackendInterface tags: - { name: cache.bin } factory: cache_factory:get arguments: [nameofbin]
See the Services topic for more on defining services.
There are two ways to remove an item from the cache:
Use deletion if a cache item is no longer useful; for instance, if the item contains references to data that has been deleted. Use invalidation if the cached item may still be useful to some callers until it has been updated with fresh data. The fact that it was fresh a short while ago may often be sufficient.
Invalidation is particularly useful to protect against stampedes. Rather than having multiple concurrent requests updating the same cache item when it expires or is deleted, there can be one request updating the cache, while the other requests can proceed using the stale value. As soon as the cache item has been updated, all future requests will use the updated value.
The fourth argument of the set() method can be used to specify cache tags, which are used to identify which data is included in each cache item. A cache item can have multiple cache tags (an array of cache tags), and each cache tag is a string. The convention is to generate cache tags of the form [prefix]:[suffix]. Usually, you'll want to associate the cache tags of entities, or entity listings. You won't have to manually construct cache tags for them — just get their cache tags via \Drupal\Core\Cache\CacheableDependencyInterface::getCacheTags() and \Drupal\Core\Entity\EntityTypeInterface::getListCacheTags(). Data that has been tagged can be invalidated as a group: no matter the Cache ID (cid) of the cache item, no matter in which cache bin a cache item lives; as long as it is tagged with a certain cache tag, it will be invalidated.
Because of that, cache tags are a solution to the cache invalidation problem:
A typical scenario: a user has modified a node that appears in two views, three blocks and on twelve pages. Without cache tags, we couldn't possibly know which cache items to invalidate, so we'd have to invalidate everything: we had to sacrifice effectiveness to achieve correctness. With cache tags, we can have both.
Example:
// A cache item with nodes, users, and some custom module data. $tags = array( 'my_custom_tag', 'node:1', 'node:3', 'user:7', ); \Drupal::cache()->set($cid, $data, CacheBackendInterface::CACHE_PERMANENT, $tags); // Invalidate all cache items with certain tags. \Drupal\Core\Cache\Cache::invalidateTags(array('user:1'));
Drupal is a content management system, so naturally you want changes to your content to be reflected everywhere, immediately. That's why we made sure that every entity type in Drupal 8 automatically has support for cache tags: when you save an entity, you can be sure that the cache items that have the corresponding cache tags will be invalidated. This also is the case when you define your own entity types: you'll get the exact same cache tag invalidation as any of the built-in entity types, with the ability to override any of the default behavior if needed. See \Drupal\Core\Cache\CacheableDepenencyInterface::getCacheTags(), \Drupal\Core\Entity\EntityTypeInterface::getListCacheTags(), \Drupal\Core\Entity\Entity::invalidateTagsOnSave() and \Drupal\Core\Entity\Entity::invalidateTagsOnDelete().
Some computed data depends on contextual data, such as the user roles of the logged-in user who is viewing a page, the language the page is being rendered in, the theme being used, etc. When caching the output of such a calculation, you must cache each variation separately, along with information about which variation of the contextual data was used in the calculatation. The next time the computed data is needed, if the context matches that for an existing cached data set, the cached data can be reused; if no context matches, a new data set can be calculated and cached for later use.
Cache contexts are services tagged with 'cache.context', whose classes implement \Drupal\Core\Cache\Context\CacheContextInterface. See https://www.drupal.org/developing/api/8/cache/contexts for more information on cache contexts, including a list of the contexts that exist in Drupal core, and information on how to define your own contexts. See the Services and the Dependency Injection Container topic for more information about services.
Typically, the cache context is specified as part of the #cache property of a render array; see the Caching section of the Render API overview topic for details.
By default cached data is stored in the database. This can be configured though so that all cached data, or that of an individual cache bin, uses a different cache backend, such as APCu or Memcache, for storage.
In a settings.php file, you can override the service used for a particular cache bin. For example, if your service implementation of \Drupal\Core\Cache\CacheBackendInterface was called cache.custom, the following line would make Drupal use it for the 'cache_render' bin:
$settings['cache']['bins']['render'] = 'cache.custom';
Additionally, you can register your cache implementation to be used by default for all cache bins with:
$settings['cache']['default'] = 'cache.custom';
Finally, you can chain multiple cache backends together, see \Drupal\Core\Cache\ChainedFastBackend and \Drupal\Core\Cache\BackendChain.
https://www.drupal.org/node/1884796
Name | Location | Description |
---|---|---|
Drupal::cache | core/lib/Drupal.php | Returns the requested cache bin. |
Name | Location | Description |
---|---|---|
BackendChain | core/lib/Drupal/Core/Cache/BackendChain.php | Defines a chained cache implementation for combining multiple cache backends. |
Cache | core/lib/Drupal/Core/Cache/Cache.php | Helper methods for cache. |
CacheableMetadata | core/lib/Drupal/Core/Cache/CacheableMetadata.php | Defines a generic class for passing cacheability metadata. |
CacheCollector | core/lib/Drupal/Core/Cache/CacheCollector.php | Default implementation for CacheCollectorInterface. |
ChainedFastBackend | core/lib/Drupal/Core/Cache/ChainedFastBackend.php | Defines a backend with a fast and a consistent backend chain. |
DatabaseBackend | core/lib/Drupal/Core/Cache/DatabaseBackend.php | Defines a default cache implementation. |
MemoryBackend | core/lib/Drupal/Core/Cache/MemoryBackend.php | Defines a memory cache implementation. |
NullBackend | core/lib/Drupal/Core/Cache/NullBackend.php | Defines a stub cache implementation. |
PhpBackend | core/lib/Drupal/Core/Cache/PhpBackend.php | Defines a PHP cache implementation. |
Name | Location | Description |
---|---|---|
CacheableDependencyInterface | core/lib/Drupal/Core/Cache/CacheableDependencyInterface.php | Defines an interface for objects which may be used by other cached objects. |
CacheBackendInterface | core/lib/Drupal/Core/Cache/CacheBackendInterface.php | Defines an interface for cache implementations. |
CacheCollectorInterface | core/lib/Drupal/Core/Cache/CacheCollectorInterface.php | Provides a caching wrapper to be used in place of large structures. |
CacheTagsChecksumInterface | core/lib/Drupal/Core/Cache/CacheTagsChecksumInterface.php | Provides checksums for cache tag invalidations. |
CacheTagsInvalidatorInterface | core/lib/Drupal/Core/Cache/CacheTagsInvalidatorInterface.php | Defines required methods for classes wanting to handle cache tag changes. |
© 2001–2016 by the original authors
Licensed under the GNU General Public License, version 2 and later.
Drupal is a registered trademark of Dries Buytaert.
https://api.drupal.org/api/drupal/core!core.api.php/group/cache/8.1.x