-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Added the documentation for the Cache component #6515
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
Closed
Closed
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
7582785
Added the documentation for the Cache component
javiereguiluz 21da04e
Used a better example
javiereguiluz 05b7ba9
Tweaked the example
javiereguiluz 401410d
Added the docs for the cache items
javiereguiluz 6acd591
Added a missing file
javiereguiluz b1c5b12
Minor fixes
javiereguiluz c6917bd
Minor syntax error
javiereguiluz fc84df8
Added a missing link
javiereguiluz 599ed0a
Added the article about Cache Pools
javiereguiluz 687910d
Updated the cache pools article
javiereguiluz 2d71222
Completed the chapter about cache pools
javiereguiluz 6d21b01
First round of fixes
javiereguiluz e1bce89
Tweaked some examples
javiereguiluz 81ec988
Updated the description of ChainAdapter
javiereguiluz c44b7c2
Added docs for ProxyAdapter
javiereguiluz 11549e2
Removed useless information
javiereguiluz 930a2d1
Simplified the explanation of the cache pools
javiereguiluz 94011a7
More tweaks
javiereguiluz cf07d4a
Added the explanation of the "version" argument
javiereguiluz f2234ed
Fixed a link
javiereguiluz 1628349
Changes recommended by reviewers
javiereguiluz 657659f
Fixed the adapter of cache pools
javiereguiluz 50f0d58
Removed a "note" and improve an example
javiereguiluz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
.. index:: | ||
single: Cache Item | ||
single: Cache Expiration | ||
single: Cache Exceptions | ||
|
||
Cache Items | ||
=========== | ||
|
||
Cache items are 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. You can freely choose the | ||
keys, but they should only contain letters (A-Z, a-z), numbers (0-9) and the | ||
``_`` and ``.`` symbols. Other common symbols (such as ``{``, ``}``, ``(``, | ||
``)``, ``/``, ``\`` and ``@``) are reserved by the PSR-6 standard for future | ||
uses. | ||
|
||
The **value** of a cache item can be any data represented by a type which is | ||
serializable by PHP, such as basic types (string, integer, float, boolean, null), | ||
arrays and objects. | ||
|
||
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 | ||
$numProducts = $cache->getItem('stats.num_products'); | ||
|
||
Then, use the :method:`Psr\\Cache\\CacheItemInterface::set` method to set | ||
the data stored in the cache item:: | ||
|
||
// storing a simple integer | ||
$numProducts->set(4711); | ||
$cache->save($numProducts); | ||
|
||
// storing an array | ||
$numProducts->set(array( | ||
'category1' => 4711, | ||
'category2' => 2387, | ||
)); | ||
$cache->save($numProducts); | ||
|
||
The key and the value of any given cache item can be obtained with the | ||
corresponding *getter* methods:: | ||
|
||
$cacheItem = $cache->getItem('exchange_rate'); | ||
// ... | ||
$key = $cacheItem->getKey(); | ||
$value = $cacheItem->get(); | ||
|
||
Cache Item Expiration | ||
~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
By default cache items are stored permanently. In practice, this "permanent | ||
storage" can vary greatly depending on the type of cache being used, as | ||
explained in the :doc:`/components/cache/cache_pools` article. | ||
|
||
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 PSR-6 | ||
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`` return | ||
values and you can safely store in the cache values such as ``false`` and ``null``. | ||
|
||
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'); | ||
|
||
if (!$latestNews->isHit()) { | ||
// do some heavy computation | ||
$news = ...; | ||
$cache->save($latestNews->set($news)); | ||
} else { | ||
$news = $latestNews->get(); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,252 @@ | ||
.. 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 file system 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 :class:`Symfony\\Component\\Cache\\Adapter\\AdapterInterface`. This | ||
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 not persisted in any way. Besides, some features explained later are | ||
not available, such as the deferred saves:: | ||
|
||
use Symfony\Component\Cache\Adapter\ArrayAdapter; | ||
|
||
$cache = new ArrayAdapter( | ||
// in seconds; applied to cache items that don't define their own lifetime | ||
// 0 means to store the cache items indefinitely (i.e. until the current PHP process finishes) | ||
$defaultLifetime = 0, | ||
// if ``true``, the values saved in the cache are serialized before storing them | ||
$storeSerialized = true | ||
); | ||
|
||
Filesystem Cache Adapter | ||
~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
This adapter is useful when you want to improve the application performance but | ||
can't install tools like APC or Redis in the server. This adapter stores the | ||
contents as regular files in a set of directories on the local file system:: | ||
|
||
use Symfony\Component\Cache\Adapter\FilesystemAdapter; | ||
|
||
$cache = new FilesystemAdapter( | ||
// the subdirectory of the main cache directory where cache items are stored | ||
$namespace = '', | ||
// in seconds; applied to cache items that don't define their own lifetime | ||
// 0 means to store the cache items indefinitely (i.e. until the files are deleted) | ||
$defaultLifetime = 0, | ||
// the main cache directory (the application needs read-write permissions on it) | ||
// if none is specified, a directory is created inside the system temporary directory | ||
$directory = null | ||
); | ||
|
||
APCu Cache Adapter | ||
~~~~~~~~~~~~~~~~~~ | ||
|
||
This adapter can increase the application performance very significantly, | ||
because contents are cached in the shared memory of your server, which is much | ||
faster than the file system. It requires to have installed and enabled the PHP | ||
APCu extension. It's not recommended to use it when performing lots of write and | ||
delete operations because it produces fragmentation in the APCu memory that can | ||
degrade performance significantly:: | ||
|
||
use Symfony\Component\Cache\Adapter\ApcuAdapter; | ||
|
||
$cache = new ApcuAdapter( | ||
// the string prefixed to the keys of the items stored in this cache | ||
$namespace = '', | ||
// in seconds; applied to cache items that don't define their own lifetime | ||
// 0 means to store the cache items indefinitely (i.e. until the APC memory is deleted) | ||
$defaultLifetime = 0, | ||
// if present, this string is added to the namespace to simplify the | ||
// invalidation of the entire cache (e.g. when deploying the application) | ||
$version = null | ||
); | ||
|
||
Redis Cache Adapter | ||
~~~~~~~~~~~~~~~~~~~ | ||
|
||
This adapter stores the contents in the memory of the server. Unlike the APCu | ||
adapter, it's not limited to the shared memory of the current server, so you can | ||
store contents in a cluster of servers if needed. | ||
|
||
It requires to have installed Redis and have created a connection that implements | ||
the ``\Redis``, ``\RedisArray``, ``\RedisCluster`` or ``\Predis`` classes:: | ||
|
||
use Symfony\Component\Cache\Adapter\RedisAdapter; | ||
|
||
$cache = new RedisAdapter( | ||
// the object that stores a valid connection to your Redis system | ||
\Redis $redisConnection, | ||
// the string prefixed to the keys of the items stored in this cache | ||
$namespace = '', | ||
// in seconds; applied to cache items that don't define their own lifetime | ||
// 0 means to store the cache items indefinitely (i.e. until the Redis memory is deleted) | ||
$defaultLifetime = 0 | ||
); | ||
|
||
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 simple 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)); | ||
|
||
When an item is not found in the first adapters but is found in the next ones, | ||
the ``ChainAdapter`` ensures that the fetched item is saved in all the adapters | ||
where it was missing. Since it's not possible to know the expiry date and time | ||
of a cache item, the second optional argument of ``ChainAdapter`` is the default | ||
lifetime applied to those cache items (by default it's ``0``). | ||
|
||
Proxy Cache Adapter | ||
~~~~~~~~~~~~~~~~~~~ | ||
|
||
This adapter is useful to integrate in your application cache pools not created | ||
with the Symfony Cache component. As long as those cache pools implement the | ||
``CacheItemPoolInterface`` interface, this adapter allows you to get items from | ||
that external cache and save them in the Symfony cache of your application:: | ||
|
||
use Symfony\Component\Cache\Adapter\ProxyAdapter; | ||
|
||
// ... create $nonSymfonyCache somehow | ||
$cache = new ProxyAdapter($nonSymfonyCache); | ||
|
||
The adapter accepts two additional optional arguments: the namespace (``''`` by | ||
default) and the default lifetime (``0`` by default). | ||
|
||
Another use case for this adapter is to get statistics and metrics about the | ||
cache hits (``getHits()``) and misses (``getMisses()``). | ||
|
||
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 | ||
:method:`Psr\\Cache\\CacheItemPoolInterface::save`, which stores the | ||
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 | ||
:method:`Psr\\Cache\\CacheItemPoolInterface::saveDeferred` method to mark cache | ||
items as "ready to be persisted" and then call to | ||
:method:`Psr\\Cache\\CacheItemPoolInterface::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 :method:`Psr\\Cache\\CacheItemPoolInterface::deleteItem`, | ||
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 :method:`Psr\\Cache\\CacheItemPoolInterface::deleteItems` 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 | ||
:method:`Psr\\Cache\\CacheItemPoolInterface::clear` method (which returns ``true`` | ||
when all items are successfully deleted):: | ||
|
||
// ... | ||
$cacheIsEmpty = $cache->clear(); | ||
|
||
.. _`Doctrine Cache`: https://github.com/doctrine/cache |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
Cache | ||
===== | ||
|
||
.. toctree:: | ||
:maxdepth: 2 | ||
|
||
introduction | ||
cache_items | ||
cache_pools |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Is there a difference between
$key
and'logged_users'
?