About storage adapters and patterns
The different storage adapters and patterns are a great way of implementing different functionality throughout our cache adapters, and storing them on different platforms, for example, the file system or just in memory. This recipe will tell us all about the default tools available in Zend Framework 2.
Storage adapter's implementations
Storage adapters in ZF2 are adapters used to do the actual caching of our data, meaning they also control how the data is stored. The storage adapters always implement the Zend\Cache\Storage\StorageInterface
, which contains the basic functionality that the storage adapter needs to comply with. Most of the storage adapters also extend from the Zend\Cache\Storage\Adapter\AbstractAdapter
, but no guarantee can be given for that. Aside from the StorageInterface
, storage adapters often implement additional interfaces representing enhanced functionality. These implementations obviously play a crucial role of the functionality of the adapter, so we think it is best to give a short list of implementations that the adapter can use that are defined by the framework.
AvailableSpaceCapableInterface
: This interface provides a method to check the available space for the caching.Capabilities
: This interface provides methods to check the capabilities of the Storage adapter, such as the minimum and maximum ttl (time-to-live) of the cache, or the supported data types (boolean, string, object, and so on).ClearByNamespaceInterface
: This interface has a method defined that can clear cache by the given namespace.ClearByPrefixInterface
: This interface defines a method that can clear cache by the given prefix.ClearExpiredInterface
: This interface provides a method to clear expired cache items.FlushableInterface
: This interface is able to flush the whole cache.IterableInterface
: This interface provides functionality to iterate over the cache items. Super handy toforeach
over them!OptimizableInterface
: This interface gives the ability to optimize the caching.TaggableInterface
: This interface provides methods to get and set tags for a specific cache item, and the ability to remove all the cache items through a certain tag.TotalSpaceCapableInterface
: This interface has a method that returns the total space of the cache.
Storage adapters
Now that we know the interfaces an adapter may implement, it is time to give a comprehensive list of the storage adapters available in the Zend\Cache\Storage\Adapter
namespace.
Apc caching
Apc or Alternative PHP Cache is a well known framework that heavily optimizes the PHP output and stores the compiled PHP code in the shared-memory. This way some of the opcode (operation code) doesn't have to be recompiled again as it is ready for immediate use. The Apc adapter also extends from the AbstractAdapter
.
This adapter implements the following interfaces:
AvailableSpaceCapableInterface
ClearByNamespaceInterface
ClearByPrefixInterface
FlushableInterface
IterableInterface
TotalSpaceCapableInterface
Tip
This adapter can only work if the APC extension in PHP has been enabled, please make sure that it is before trying.
Dba caching
You want to store the cache in a pre-relation dbm database, then this is your chance! This adapter can store it all neatly away in a nice database. This adapter also extends from the AbstractAdapter
.
This adapter implements the following interfaces:
AvailableSpaceCapableInterface
ClearByNamespaceInterface
ClearByPrefixInterface
FlushableInterface
IterableInterface
OptimizableInterface
TotalSpaceCapableInterface
Tip
This adapter needs the dba extension enabled in PHP before it can work, please make sure it is enabled.
File system caching
File system caching is a personal favorite, to store the cache on the good old file system, a fast and usually reliable place to place it. This adapter also extends from the AbstractAdapter
.
This adapter implements the following interfaces:
AvailableSpaceCapableInterface
ClearByNamespaceInterface
ClearByPrefixInterface
ClearExpiredInterface
FlushableInterface
IterableInterface
OptimizableInterface
TaggableInterface
TotalSpaceCapableInterface
Tip
It sounds as something really obvious, but make sure we have write permissions on the directory where we want to store the cache.
Memcached caching
The Memcached adapter stores the cache in the memory, which is a great way to store static file that don't change often and can be considered semi-static. This adapter also extends from the AbstractAdapter
. Please note that Memcached is not restricted by PHP's memory limit settings, as Memcached stores the memory outside of the PHP process in its own Memcached process.
This adapter implements the following interfaces:
AvailableSpaceCapableInterface
FlushableInterface
TotalSpaceCapableInterface
Tip
We need the memcached
PHP extension to cache through this adapter. Please make sure it is enabled on your system.
Memory caching
The Memory adapter stores all the cache in the PHP process, in comparison to the Memcached adapter, as that stores all the cache in an external Memcached process. This adapter also extends from the AbstractAdapter
.
This adapter implements the following interfaces:
AvailableSpaceCapableInterface
ClearByPrefixInterface
ClearByNamespaceInterface
ClearExpiredInterface
FlushableInterface
IterableInterface
TaggableInterface
TotalSpaceCapableInterface
Redis caching
The Redis is a key-value data store that stores the data in-memory, which is extremely well done and certainly is a caching method worth using. This adapter also extends from the AbstractAdapter
.
This adapter implements the following interfaces:
FlushableInterface
TotalSpaceCapableInterface
Tip
If we want to use this caching adapter, we need to make sure the redis
extension is loaded, otherwise this storage adapter cannot be used. Please make sure the extension is installed and enabled.
Session caching
The Session storage adapter uses the session to store our cache in. Although handy for one user at a time, this method isn't really effective for users who view the same pages as it builds up the cache every time a user initiates a session. This adapter also extends from the AbstractAdapter
.
This adapter implements the following interfaces:
ClearByPrefixInterface
FlushableInterface
IterableInterface
WinCache caching
The WinCache is an excellent adapter that is useful when running PHP on a Microsoft Windows server. WinCache supports opcode caching, file system caching, and relative path caching. This adapter also extends from the AbstractAdapter
.
This adapter implements the following interfaces:
AvailableSpaceCapableInterface
FlushableInterface
TotalSpaceCapableInterface
Tip
For this method the wincache
extension needs to be loaded, and if that wasn't all you also need to be on Microsoft Windows to, to use this.
XCache caching
The XCache is an adapter that utilizes the XCache module in PHP, which is another cache adapter like APC and is a fast opcode cacher, which is very useful. This adapter also extends from the AbstractAdapter
.
This adapter implements the following interfaces:
AvailableSpaceCapableInterface
ClearByNamespaceInterface
ClearByPrefixInterface
FlushableInterface
IterableInterface
TotalSpaceCapableInterface
Tip
This adapter requires the XCache extension to be loaded and enabled in PHP. Please make sure this is the case before trying to use the adapter.
ZendServerDisk caching
The ZendServerDisk adapter is a great file system cache adapter provided by the Zend Server application. If we have the Zend Server installed, this adapter is a great way of storing the cache on the file system as it integrates ridiculously good with the Zend Server. This adapter also extends from the AbstractAdapter
.
This adapter implements the following interfaces:
AvailableSpaceCapableInterface
ClearByNamespaceInterface
FlushableInterface
TotalSpaceCapableInterface
Tip
To make this adapter work you'll need to have the Zend Server installed, otherwise it will just throw an exception.
ZendServerShm caching
The ZendServerShm adapter also requires us to have the Zend Server installed, but if we have and we want to cache items in the shared memory (shm) then this is an amazing way of doing it, as this adapter integrates very nicely with the Zend Server. This adapter also extends from the AbstractAdapter
.
This adapter implements the following interfaces:
ClearByNamespaceInterface
FlushableInterface
TotalSpaceCapableInterface
Tip
To make this adapter work you'll need to have the Zend Server installed to make this adapter work, otherwise it will just throw an exception.
Cache patterns
When we start caching, we will quickly find ourselves in situations that are counteractive to the performance while we just wanted everything to go faster. That is why there are classes in ZF2 that are called Cache patterns, which are there for us to use when we want to overcome some common problems.
Like the adapters, patterns are also always implementations of an interface; in this case the PatternInterface
. And because we usually also want some basic functionality, most of the patterns also extend from the AbstractPattern
class.
Options for the patterns are defined through the PatternOptions
class, which is explained a bit further on as well.
The CallbackCache pattern
What do we want, a callback or the cache? Sometimes we just don't know for sure, so we'll let the pattern to figure it out itself! The CallbackCache
pattern first makes sure if there is a result for our callback already defined in the cache, and if so, returns that. If the result is not in the cache yet, it will call our callback function, put our output in the result and then return that. Either way, the second time that callback is being handled, we will get our cache back. So if this is a long running method, it will be considerably faster when we don't have to execute the code again.
This pattern also takes the arguments for that callback in consideration, which means you don't really have to worry much about the callback providing you with the wrong results!
This Pattern uses the AbstractPattern
class.
The CaptureCache pattern
The CaptureCache
pattern captures the output we are sending to the browser by initiating an ob_start()
and ob_implicit_flush()
. We can then do a check if the cache exists every time we sent the output out, so that instead of generating it we just display the output.
This pattern uses the AbstractPattern
class.
Tip
This pattern does not automatically output cache once defined, the developer needs to get the cache themselves first before using the start method. If we want to output cache when it exists before generating new content we should use the OutputCache
pattern.
The ClassCache pattern
The
ClassCache
pattern caches the output of a class method call and returns that instead of the actual call. But of course, this only happens when the cache is actually available, otherwise it will just do the method call and cache the results. The class name (not the object) needs to be set in the PatternOptions::setClass
to make it work.
This pattern uses the AbstractPattern
class.
The ObjectCache pattern
The
ObjectCache
pattern caches the object and can be used to call methods upon its retrieval, very handy if we have objects that need to persistent for a very long time. The object needs to be set in the PatternOptions::setObject
to make it work.
This pattern uses the AbstractPattern
class.
The OutputCache pattern
The OutputCache
pattern outputs the cache if it is defined. If not, then OutputCache caches the output and sets the cache upon script end (or call to the end method, whichever comes first).
This pattern uses the AbstractPattern
class.
The PatternOptions pattern
The
PatternOptions
pattern can be used to set options or get options from and to the patterns (setOptions
and getOptions
respectively). For most patterns some form of options need to be set before the pattern can be used. Think here about the setStorage
method for example, because the pattern needs to know the storage adapter before it can actually store things.
Explaining the difference
Storage adapters store and retrieve the cache data. We can set options to determine the length of the validity or perhaps check if the cache is full or not, but we can't determine how it is stored, as that is part of the adapter's job description.
Patterns however don't store anything themselves. They determine if they need to store anything by checking if the cache already exists, or if the cache is what we expect it to be (for example, when we use a different method call or different arguments to that call). They do tell the adapters what they want to retrieve and store, so that the adapter then can find out how to retrieve it from the actual storage again.
In a developer's eye we would rather be using patterns before we would want to use the adapters, as we'd not want to interfere with the adapters too much if there are already patterns doing most of the work for us.