-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added the documentation for the Cache component #6515
Changes from 11 commits
7582785
21da04e
05b7ba9
401410d
6acd591
b1c5b12
c6917bd
fc84df8
599ed0a
687910d
2d71222
6d21b01
e1bce89
81ec988
c44b7c2
11549e2
930a2d1
94011a7
cf07d4a
f2234ed
1628349
657659f
50f0d58
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
.. index:: | ||
single: Cache Item | ||
single: Cache Expiration | ||
single: Cache Exceptions | ||
|
||
Cache Items | ||
=========== | ||
|
||
Cache items are each one of the information units stored in the cache as a | ||
key/value pair. In the Cache component they are represented by the | ||
:class:`Symfony\\Component\\Cache\\CacheItem` class. | ||
|
||
Cache Item Keys and Values | ||
-------------------------- | ||
|
||
The **key** of a cache item is a UTF-8 encoded string which acts as its | ||
identifier, so it must be unique for each cache pool. The PSR-6 standard limits | ||
the key length to 64 characters, but Symfony allows to use longer keys (they are | ||
encoded internally to reduce their size). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They are not encoded for all adapters but still the length is not limited. I suggest removing these brackets. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd advocate for keeping to 64 characters anyway, for interoperability (the whole point of PSR interfaces...) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If Symfony follows this 64-char limit internally and it doesn't enforce it externally, I think we should remove this information. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It does not matter what Symfony Cache does internally. The interface only guarantees that keys up to 64 characters will work. Say, the user swap out Symfony Cache for another PSR-6 cache, things might break if they go over that limit. And we should encourage users to stay within the limit - warn them of the risk of doing otherwise. |
||
|
||
You can freely chose the keys, but they can only contain letters (A-Z, a-z), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. they can -> they should? (because we allow any other non-reserved chars) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. chose -> choose |
||
numbers (0-9) and the ``_`` and ``.`` symbols. Other common symbols (such as | ||
``{``, ``}``, ``(``, ``)``, ``/``, ``\`` and ``@``) are reserved for future uses. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. by PSR-6? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we link to the relevant sections in PSR-6? |
||
|
||
The **value** of a cache item can be any data represented by a type which is | ||
serializable by PHP, such as basic types (strings, integers, floats, boolean, | ||
nulls), arrays and objects. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. null |
||
|
||
Creating Cache Items | ||
-------------------- | ||
|
||
Cache items are created with the ``getItem($key)`` method of the cache pool. The | ||
argument is the key of the item:: | ||
|
||
// $cache pool object was created before | ||
$cachedNumProducts = $cache->getItem('stats.num_products'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. $pool->getItem(...? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does |
||
|
||
Then, use the ``set($value)`` method to set the data stored in the cache item:: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's use an API link here |
||
|
||
// storing a simple integer | ||
$cachedNumProducts->set(4711); | ||
|
||
// storing an array | ||
$cachedNumProducts->set(array( | ||
'category1' => 4711, | ||
'category2' => 2387, | ||
)); | ||
|
||
.. note:: | ||
|
||
Creating a cache item and setting its value is not enough to save it in the | ||
cache. You must execute the ``save($cacheItem)`` method explicitly on the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't put arguments in the parenthesis when refering to methods |
||
cache pool. | ||
|
||
The key and the value of any given cache item can be obtained with the | ||
corresponding *getter* methods:: | ||
|
||
$cacheItem = $cache->getItem('logged_users'); | ||
// ... | ||
$key = $cacheItem->getKey(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a difference between |
||
$value = $cacheItem->get(); | ||
|
||
Cache Item Expiration | ||
~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
By default cache items are stored "permanently", which in practice means "as long | ||
as allowed by the cache implementation used". | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as long as the cache pool is not cleared also? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that's already understood. This is talking about expiration. Clearing is a different matter. |
||
|
||
However, in some applications it's common to use cache items with a shorter | ||
lifespan. Consider for example an application which caches the latest news just | ||
for one minute. In those cases, use the ``expiresAfter()`` method to set the | ||
number of seconds to cache the item:: | ||
|
||
$latestNews = $cache->getItem('latest_news'); | ||
$latestNews->expiresAfter(60); // 60 seconds = 1 minute | ||
|
||
// this method also accepts \DateInterval instances | ||
$latestNews->expiresAfter(DateInterval::createFromDateString('1 hour')); | ||
|
||
Cache items define another related method called ``expiresAt()`` to set the | ||
exact date and time when the item will expire:: | ||
|
||
$mostPopularNews = $cache->getItem('popular_news'); | ||
$mostPopularNews->expiresAt(new \DateTime('tomorrow')); | ||
|
||
Cache Item Hits and Misses | ||
-------------------------- | ||
|
||
Using a cache mechanism is important to improve the application performance, but | ||
it should not be required to make the application work. In fact, the Cache | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the "cache standard"? |
||
standard states that caching errors should not result in application failures. | ||
|
||
In practice this means that the ``getItem()`` method always returns an object | ||
which implements the ``Psr\Cache\CacheItemInterface`` interface, even when the | ||
cache item doesn't exist. Therefore, you don't have to deal with ``null`` values. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This allows caching e.g. |
||
|
||
In order to decide if the returned object is correct or not, caches use the | ||
concept of hits and misses: | ||
|
||
* **Cache Hits** occur when the requested item is found in the cache, its value | ||
is not corrupted or invalid and it hasn't expired; | ||
* **Cache Misses** are the opposite of hits, so they occur when the item is not | ||
found in the cache, its value is corrupted or invalid for any reason or the | ||
item has expired. | ||
|
||
Cache item objects define a boolean ``isHit()`` method which returns ``true`` | ||
for cache hits:: | ||
|
||
$latestNews = $cache->getItem('latest_news'); | ||
$latestNews->expiresAfter(60); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure this example is the good one here, i'd suggest something like the following, which is the canonical snippet when dealing with arbitrary cached values to me:
|
||
|
||
// check the item a few seconds after creating it | ||
$isHit = $latestNews->isHit(); // true | ||
|
||
// check the item 10 minutes after creating it | ||
$isHit = $latestNews->isHit(); // false |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
.. index:: | ||
single: Cache Pool | ||
single: APC Cache, APCu Cache | ||
single: Doctrine Cache | ||
single: Redis Cache | ||
|
||
Cache Pools | ||
=========== | ||
|
||
Cache Pools are the logical repositories of cache items. They perform all the | ||
common operations on items, such as saving them or looking for them. Cache pools | ||
are independent from the actual cache implementation. Therefore, applications | ||
can keep using the same cache pool even if the underlying cache mechanism | ||
changes from a filesystem based cache to a Redis or database based cache. | ||
|
||
Creating Cache Pools | ||
-------------------- | ||
|
||
Cache Pools are created through the **cache adapters**, which are classes that | ||
implement the :class:`Psr\\Cache\\CacheItemPoolInterface` interface. This | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "which" refers to "cache adapters", these implement AdapterInterface (which extends CacheItemPoolInterface). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand this comment. Please tell me how to reword this paragraph:
Thanks. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With the current situation, it seems like I need to implement There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. true for symfony derivated adapters (AdapterInterface extends CacheItemPoolInterface) |
||
component provides several adapters ready to use in your applications. | ||
|
||
Array Cache Adapter | ||
~~~~~~~~~~~~~~~~~~~ | ||
|
||
This adapter is only useful for testing purposes because contents are stored in | ||
memory and no persisted in any way. Besides, some features explained later are | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not persisted |
||
not available, such as the deferred saves:: | ||
|
||
use Symfony\Component\Cache\Adapter\ArrayAdapter; | ||
|
||
$cache = new ArrayAdapter($defaultLifetime = 0, $storeSerialized = true); | ||
|
||
``defaultLifetime`` | ||
**type**: integer, **default value**: ``0`` | ||
The default lifetime, in seconds, applied to cache items that don't define | ||
their own lifetime. The default value (``0``) means an "infinite" lifetime, | ||
but this adapter destroys the cache once the current PHP execution finishes. | ||
|
||
``storeSerialized`` | ||
**type**: boolean, **default value**: ``true`` | ||
If ``true``, the values saved in the cache are serialized before storing them. | ||
|
||
Filesystem Cache Adapter | ||
~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
This adapter is useful when you want to improve the application performance but | ||
can't install in the server tools like APC or Redis:: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It stores cached items in a set of directories on the local file system. |
||
|
||
use Symfony\Component\Cache\Adapter\FilesystemAdapter; | ||
|
||
$cache = new FilesystemAdapter($namespace = '', $defaultLifetime = 0, $directory = null); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. $pool? |
||
|
||
``namespace`` | ||
**type**: string, **default value**: ``''`` (an empty string) | ||
The subdirectory created inside the main cache directory (defined in the | ||
third argument) to store the cache items. | ||
|
||
``defaultLifetime`` | ||
**type**: integer, **default value**: ``0`` | ||
The default lifetime, in seconds, applied to cache items that don't define | ||
their own lifetime. The default value (``0``) means an "infinite" lifetime, | ||
which this adapter respects because items are actually persisted. | ||
|
||
``directory`` | ||
**type**: string, **default value**: ``null`` | ||
The directory where the cache items are stored as files. Make sure that this | ||
directory has read-write permissions for your application. If no directory | ||
is defined, a new directory called ``symfony-cache/`` is created in the | ||
system's temporary directory. | ||
|
||
APCu Cache Adapter | ||
~~~~~~~~~~~~~~~~~~ | ||
|
||
This adapter can increase the application performance very significantly, because | ||
contents are cached in the memory of your server, which is much faster than the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in the shared memory |
||
filesystem. It requires to have installed and enabled the PHP APC extension:: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that APCu should be recommended for mostly-append populating scenarios. Having lots of delete&writes creates fragmentation which can degrade performance significantly. |
||
|
||
use Symfony\Component\Cache\Adapter\ApcuAdapter; | ||
|
||
$cache = new ApcuAdapter($namespace = '', $defaultLifetime = 0); | ||
|
||
``namespace`` | ||
**type**: string, **default value**: ``''`` (an empty string) | ||
The string prefixed to the keys of the items stored in this cache. | ||
|
||
``defaultLifetime`` | ||
**type**: integer, **default value**: ``0`` | ||
The default lifetime, in seconds, applied to cache items that don't define | ||
their own lifetime. The default value (``0``) means an "infinite" lifetime, | ||
which in this adapter ends when the web server is restarted or the APC memory | ||
is deleted in any other way. | ||
|
||
Redis Cache Adapter | ||
~~~~~~~~~~~~~~~~~~~ | ||
|
||
This adapter, similarly to APCu adapter, can increase the application performance | ||
very significantly, because contents are cached in the memory of your server. It | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This description makes it as if Redis is like APCu (both store content "in the memory of your server"). |
||
requires to have installed Redis and have created a connection that implements | ||
``\Redis`` class:: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the Redis |
||
|
||
use Symfony\Component\Cache\Adapter\RedisAdapter; | ||
|
||
$cache = new RedisAdapter(\Redis $redisConnection, $namespace = '', $defaultLifetime = 0); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. $pool? |
||
|
||
``redisConnection`` | ||
**type**: ``\Redis``, **default value**: (none, this argument is mandatory) | ||
The object that represents a valid connection to your Redis system. | ||
|
||
``namespace`` | ||
**type**: string, **default value**: ``''`` (an empty string) | ||
The string prefixed to the keys of the items stored in this cache. | ||
|
||
``defaultLifetime`` | ||
**type**: integer, **default value**: ``0`` | ||
The default lifetime, in seconds, applied to cache items that don't define | ||
their own lifetime. The default value (``0``) means an "infinite" lifetime, | ||
which in this adapter ends when the server is restarted or the Redis memory | ||
is deleted in any other way. | ||
|
||
Chain Cache Adapter | ||
~~~~~~~~~~~~~~~~~~~ | ||
|
||
This adapter allows to combine any number of the previous adapters. Cache items | ||
are fetched from the first adapter which contains them. Besides, cache items are | ||
saved in all the given adapters, so this is a quick way of creating a cache | ||
replication:: | ||
|
||
use Symfony\Component\Cache\Adapter\ApcuAdapter; | ||
use Symfony\Component\Cache\Adapter\ChainAdapter; | ||
use Symfony\Component\Cache\Adapter\FilesystemAdapter; | ||
|
||
$apcCache = new ApcuAdapter(); | ||
$fileCache = new FilesystemAdapter(); | ||
|
||
$cache = new ChainAdapter(array($apcCache, $fileCache)); | ||
|
||
The second optional argument of ``ChainAdapter`` is the ``maxLifetime`` (default | ||
``0``) which is the maximum lifetime of items propagated from lower adapters to | ||
upper ones. | ||
|
||
.. TODO: I don't understand the previous phrase, which is copied from the ChainAdapter code. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when an item is not found in the first pool but is found in the second, the ChainAdapter ensures that the just fetched item is saved in the first pool where it were missing. But with which lifetime? Since there is no way to know of much time the item will remain in the second adapter where it were found, we need a default value, here comes $maxLifetime There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the comment. I understand this now. However, I don't understand why we need this. If an item is found in the second pool, we now when expires it. Why cannot we create the item in the first pool and set its expiration with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we do not know when it expires, that's exactly the point There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How can't you know when an existing item expires? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How can you know when an existing item expires? :) |
||
|
||
Proxy Cache Adapter | ||
~~~~~~~~~~~~~~~~~~~ | ||
|
||
.. TODO: what is this adapter useful for? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Two use cases: PSR-6 interop of cache items implementations. Without it, you can't fetch a cache item from a non-symfony pool and save it in a Symfony one. The second use case if getting stats about hits/misses in the current script context (see getHits/getMisses functions). |
||
|
||
Doctrine Cache Adapter | ||
~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
This adapter wraps any `Doctrine Cache`_ provider so you can use them in your | ||
application as if they were Symfony Cache adapters:: | ||
|
||
use Doctrine\Common\Cache\SQLite3Cache; | ||
use Symfony\Component\Cache\Adapter\DoctrineAdapter; | ||
|
||
$doctrineCache = new SQLite3(__DIR__.'/cache/data.sqlite'); | ||
$symfonyCache = new DoctrineAdapter($doctrineCache); | ||
|
||
This adapter also defines two optional arguments called ``namespace`` (default: | ||
``''``) and ``defaultLifetime`` (default: ``0``) and adapts them to make them | ||
work in the underlying Doctrine cache. | ||
|
||
Looking for Cache Items | ||
----------------------- | ||
|
||
Cache Pools define three methods to look for cache items. The most common method | ||
is ``getItem($key)``, which returns the cache item identified by the given key:: | ||
|
||
use Symfony\Component\Cache\Adapter\FilesystemAdapter; | ||
|
||
$cache = new FilesystemAdapter('app.cache') | ||
$latestNews = $cache->getItem('latest_news'); | ||
|
||
If no item is defined for the given key, the method doesn't return a ``null`` | ||
value but an empty object which implements the :class:`Symfony\\Component\\Cache\\CacheItem` | ||
class. | ||
|
||
If you need to fetch several cache items simultaneously, use instead the | ||
``getItems(array($key1, $key2, ...))`` method:: | ||
|
||
// ... | ||
$stocks = $cache->getItems(array('AAPL', 'FB', 'GOOGL', 'MSFT')); | ||
|
||
Again, if any of the keys doesn't represent a valid cache item, you won't get | ||
a ``null`` value but an empty ``CacheItem`` object. | ||
|
||
The last method related to fetching cache items is ``hasItem($key)``, which | ||
returns ``true`` if there is a cache item identified by the given key:: | ||
|
||
// ... | ||
$hasBadges = $cache->hasItem('user_'.$userId.'_badges'); | ||
|
||
Saving Cache Items | ||
------------------ | ||
|
||
The most common method to save cache items is ``save($item)``, which stores the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's use API links (same below for the other methods) |
||
item in the cache immediately (it returns ``true`` if the item was saved or | ||
``false`` if some error occurred):: | ||
|
||
// ... | ||
$userFriends = $cache->get('user_'.$userId.'_friends'); | ||
$userFriends->set($user->getFriends()); | ||
$isSaved = $cache->save($userFriends); | ||
|
||
Sometimes you may prefer to not save the objects immediately in order to | ||
increase the application performance. In those cases, use the | ||
``saveDeferred($item)`` method to mark cache items as "ready to be persisted" | ||
and then call to ``commit()`` method when you are ready to persist them all:: | ||
|
||
// ... | ||
$isQueued = $cache->saveDeferred($userFriends); | ||
// ... | ||
$isQueued = $cache->saveDeferred($userPreferences); | ||
// ... | ||
$isQueued = $cache->saveDeferred($userRecentProducts); | ||
// ... | ||
$isSaved = $cache->commit(); | ||
|
||
The ``saveDeferred()`` method returns ``true`` when the cache item has been | ||
successfully added to the "persist queue" and ``false`` otherwise. The ``commit()`` | ||
method returns ``true`` when all the pending items are successfully saved or | ||
``false`` otherwise. | ||
|
||
Removing Cache Items | ||
-------------------- | ||
|
||
Cache Pools include methods to delete a cache item, some of them or all of them. | ||
The most common is ``deleteItem($key)``, which deletes the cache item identified | ||
by the given key (it returns ``true`` when the item is successfully deleted or | ||
doesn't exist and ``false`` otherwise):: | ||
|
||
// ... | ||
$isDeleted = $cache->deleteItem('user_'.$userId); | ||
|
||
Use the ``deleteItems(array($key1, $key2, ...))`` method to delete several cache | ||
items simultaneously (it returns ``true`` only if all the items have been deleted, | ||
even when any or some of them don't exist):: | ||
|
||
// ... | ||
$areDeleted = $cache->deleteItems(array('category1', 'category2')); | ||
|
||
Finally, to remove all the cache items stored in the pool, use the ``clear()`` | ||
method (which returns ``true`` when all items are successfully deleted):: | ||
|
||
// ... | ||
$cacheIsEmpty = $cache->clear(); | ||
|
||
.. _`Doctrine Cache`: https://github.com/doctrine/cache |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
Cache | ||
===== | ||
|
||
.. toctree:: | ||
:maxdepth: 2 | ||
|
||
introduction | ||
cache_items | ||
cache_pools |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cache items are
each one of theinformation units (or looks strange to me)