Caching. CakePHP CakePHP
CakePHP is a rapid development framework for PHP that provides structure and a foundation to help you create applications in less time. It encourages you to follow conventions and is opinionated to promote consistent code. CakePHP makes the process of building web applications a lot easier. It provides you with a toolbox of tools and libraries to help you write less code and deliver more functionality.
Advertisement
Advertisement
CHAPTER 15
Caching
class Cake\Cache\Cache
Caching is frequently used to reduce the time it takes to create or read from other resources. Caching is often used to make reading from expensive resources less expensive. You can easily store the results of expensive queries, or remote webservice access that doesn’t frequently change in a cache. Once in the cache, re-reading the stored resource from the cache is much cheaper than accessing the remote resource.
Caching in CakePHP is primarily facilitated by the Cache class. This class provides a set of static methods that provide a uniform API to dealing with all different types of Caching implementations. CakePHP comes with several cache engines built-in, and provides an easy system to implement your own caching systems.
The built-in caching engines are:
• FileCache File cache is a simple cache that uses local files. It is the slowest cache engine, and doesn’t provide as many features for atomic operations. However, since disk storage is often quite cheap, storing large objects, or elements that are infrequently written work well in files.
• ApcCache APC cache uses the PHP APC
1 extension. This extension uses shared memory on the webserver to store objects. This makes it very fast, and able to provide atomic read/write features.
• Wincache Wincache uses the Wincache
2 extension. Wincache is similar to APC in features and performance, but optimized for Windows and IIS.
• XcacheEngine Xcache
3 is a PHP extension that provides similar features to APC.
• MemcachedEngine Uses the Memcached
4 vides better performance.
extension. It also interfaces with memcache but pro-
• RedisEngine Uses the phpredis
5 extension. Redis provides a fast and persistent cache system similar to memcached, also provides atomic operations.
1 http://php.net/apc
2 http://php.net/wincache
3 http://xcache.lighttpd.net/
4 http://php.net/memcached
5 https://github.com/nicolasff/phpredis
485
CakePHP Cookbook Documentation, Release 3.x
Regardless of the CacheEngine you choose to use, your application interacts with
Cake\Cache\Cache
in a consistent manner. This means you can easily swap cache engines as your application grows.
Configuring Cache Class
static Cake\Cache\Cache::config($key, $config = null)
Configuring the Cache class can be done anywhere, but generally you will want to configure Cache during bootstrapping. The config/app.php file is the conventional location to do this. You can configure as many cache configurations as you need, and use any mixture of cache engines. CakePHP uses two cache configurations internally. _cake_core_ is used for storing file maps, and parsed results of
Internationalization
& Localization
files. _cake_model_, is used to store schema descriptions for your applications models.
If you are using APC or Memcached you should make sure to set unique keys for the core caches. This will prevent multiple applications from overwriting each other’s cached data.
Using multiple configurations also lets you incrementally change the storage as needed. For example in your config/app.php you could put the following:
// ...
'Cache' => [
'short' => [
'className' => 'File' ,
'duration' => '+1 hours' ,
'path' => CACHE,
'prefix' => 'cake_short_'
],
// Using a fully namespaced name.
'long' => [
'className' => 'Cake\Cache\Engine\FileEngine' ,
'duration' => '+1 week' ,
'probability' => 100 ,
'path' => CACHE .
'long' .
DS,
]
]
// ...
Configuration options can also be provided as a
DSN
string. This is useful when working with environment variables or
PaaS
providers:
Cache :: config ( 'short' , [
'url' => 'memcached://user:password@cache-host/?timeout=3600&prefix=myapp_' ,
]);
When using a DSN string you can define any additional parameters/options as query string arguments.
You can also configure Cache engines at runtime:
// Using a short name
Cache :: config ( 'short' , [
'className' => 'File' ,
'duration' => '+1 hours' ,
'path' => CACHE,
486 Chapter 15. Caching
CakePHP Cookbook Documentation, Release 3.x
]);
'prefix' => 'cake_short_'
// Using a fully namespaced name.
Cache :: config ( 'long' , [
'className' => 'Cake\Cache\Engine\FileEngine' ,
'duration' => '+1 week' ,
'probability' => 100 ,
'path' => CACHE .
'long' .
DS,
]);
// Using a constructed object.
$object =
new
FileEngine( $config );
Cache :: config ( 'other' , $object );
The name of these configurations ‘short’ or ‘long’ is used as the $config parameter for
Cake\Cache\Cache::write()
and
Cake\Cache\Cache::read()
engines you can refer to the class name using the following syntaxes:
• Short classname without ‘Engine’ or a namespace. This will infer that you want to use a Cache engine in Cake\Cache\Engine or App\Cache\Engine.
• Using
plugin syntax
which allows you to load engines from a specific plugin.
• Using a fully qualified namespaced classname. This allows you to use classes located outside of the conventional locations.
• Using an object that extends the CacheEngine class.
Note: When using the FileEngine you might need to use the mask option to ensure cache files are made with the correct permissions.
Removing Configured Cache Engines
static Cake\Cache\Cache::drop($key)
Once a configuration is created you cannot change it. Instead you should drop the configuration and recreate it using
Cake\Cache\Cache::drop()
and
Cake\Cache\Cache::config()
cache engine will remove the config and destroy the adapter if it was constructed.
Writing to a Cache
static Cake\Cache\Cache::write($key, $value, $config = ‘default’)
Cache::write() will write a $value to the Cache. You can read or delete this value later by referring to it by $key. You may specify an optional configuration to store the cache in as well. If no $config is specified, default will be used. Cache::write() can store any type of object and is ideal for storing results of model finds:
Writing to a Cache 487
CakePHP Cookbook Documentation, Release 3.x
if
(( $posts = Cache :: read ( 'posts' )) ===
false
) {
$posts = $someService -> getAllPosts ();
Cache :: write ( 'posts' , $posts );
}
Using Cache::write() and Cache::read() to easily reduce the number of trips made to the database to fetch posts.
Note: If you plan to cache the result of queries made with the CakePHP ORM, it is better to use the built-in cache capabilities of the Query object as described in the
Caching Loaded Results
section
Writing Multiple Keys at Once
static Cake\Cache\Cache::writeMany($data, $config = ‘default’)
You may find yourself needing to write multiple cache keys at once. While you can use multiple calls to write(), writeMany() allows CakePHP to use more efficient storage API’s where available. For example using writeMany() save multiple network connections when using Memcached:
$result = Cache :: writeMany ([
'article-' .
$slug => $article ,
'article-' .
$slug .
'-comments' => $comments
]);
// $result will contain
[ 'article-first-post' =>
true
, 'article-first-post-comments' =>
true
]
Read Through Caching
static Cake\Cache\Cache::remember($key, $callable, $config = ‘default’)
Cache makes it easy to do read-through caching. If the named cache key exists, it will be returned. If the key does not exist, the callable will be invoked and the results stored in the cache at the provided key.
For example, you often want to cache remote service call results. You could use remember() to make this simple:
class IssueService
{
public function
allIssues ( $repo )
{
return
Cache :: remember ( $repo .
'-issues' ,
function
()
use
( $repo ) {
return
$this -> fetchAll ( $repo );
});
}
}
488 Chapter 15. Caching
CakePHP Cookbook Documentation, Release 3.x
Reading From a Cache
static Cake\Cache\Cache::read($key, $config = ‘default’)
Cache::read() is used to read the cached value stored under $key from the $config. If $config is null the default config will be used. Cache::read() will return the cached value if it is a valid cache or false if the cache has expired or doesn’t exist. The contents of the cache might evaluate false, so make sure you use the strict comparison operators: === or !==.
For example:
$cloud = Cache :: read ( 'cloud' );
if
( $cloud !==
false
) {
return
$cloud ;
}
// Generate cloud data
// ...
// Store data in cache
Cache :: write ( 'cloud' , $cloud );
return
$cloud ;
Reading Multiple Keys at Once
static Cake\Cache\Cache::readMany($keys, $config = ‘default’)
After you’ve written multiple keys at once, you’ll probably want to read them as well. While you could use multiple calls to read(), readMany() allows CakePHP to use more efficient storage API’s where available. For example using readMany() save multiple network connections when using Memcached:
$result = Cache :: readMany ([
'article-' .
$slug ,
'article-' .
$slug .
'-comments'
]);
// $result will contain
[ 'article-first-post' => '...' , 'article-first-post-comments' => '...' ]
Deleting From a Cache
static Cake\Cache\Cache::delete($key, $config = ‘default’)
Cache::delete() will allow you to completely remove a cached object from the store:
// Remove a key
Cache :: delete ( 'my_key' );
Reading From a Cache 489
CakePHP Cookbook Documentation, Release 3.x
Deleting Multiple Keys at Once
static Cake\Cache\Cache::deleteMany($keys, $config = ‘default’)
After you’ve written multiple keys at once, you may want to delete them. While you could use multiple calls to delete(), deleteMany() allows CakePHP to use more efficient storage API’s where available. For example using deleteMany() save multiple network connections when using Memcached:
$result = Cache :: deleteMany ([
'article-' .
$slug ,
'article-' .
$slug .
'-comments'
]);
// $result will contain
[ 'article-first-post' =>
true
, 'article-first-post-comments' =>
true
]
Clearing Cached Data
static Cake\Cache\Cache::clear($check, $config = ‘default’)
Destroy all cached values for a cache configuration. In engines like: Apc, Memcached, and Wincache, the cache configuration’s prefix is used to remove cache entries. Make sure that different cache configurations have different prefixes:
// Will only clear expired keys.
Cache :: clear (
true
);
// Will clear all keys.
Cache :: clear (
false
); static Cake\Cache\Cache::gc($config)
Garbage collects entries in the cache configuration. This is primarily used by FileEngine. It should be implemented by any Cache engine that requires manual eviction of cached data.
Using Cache to Store Counters
static Cake\Cache\Cache::increment($key, $offset = 1, $config = ‘default’) static Cake\Cache\Cache::decrement($key, $offset = 1, $config = ‘default’)
Counters for various things are easily stored in a cache. For example, a simple countdown for remaining
‘slots’ in a contest could be stored in Cache. The Cache class exposes atomic ways to increment/decrement counter values in an easy way. Atomic operations are important for these values as it reduces the risk of contention, and ability for two users to simultaneously lower the value by one, resulting in an incorrect value.
After setting an integer value you can manipulate it using increment() and decrement():
490 Chapter 15. Caching
CakePHP Cookbook Documentation, Release 3.x
Cache :: write ( 'initial_count' , 10 );
// Later on
Cache :: decrement ( 'initial_count' );
// Or
Cache :: increment ( 'initial_count' );
Note:
Incrementing and decrementing do not work with FileEngine. You should use APC, Wincache,
Redis or Memcached instead.
Using Cache to Store Common Query Results
You can greatly improve the performance of your application by putting results that infrequently change, or that are subject to heavy reads into the cache.
A perfect example of this are the results from
Cake\ORM\Table::find()
The Query object allows you to cache results using the cache() method. See the
Caching Loaded Results
section for more information.
Using Groups
Sometimes you will want to mark multiple cache entries to belong to certain group or namespace. This is a common requirement for mass-invalidating keys whenever some information changes that is shared among all entries in the same group. This is possible by declaring the groups in cache configuration:
Cache :: config ( 'site_home' , [
'className' => 'Redis' ,
'duration' => '+999 days' ,
'groups' => [ 'comment' , 'article' ]
]);
Cake\Cache\Cache::clearGroup(
$group , $config = ‘default’)
Let’s say you want to store the HTML generated for your homepage in cache, but would also want to automatically invalidate this cache every time a comment or post is added to your database. By adding the groups comment and article, we have effectively tagged any key stored into this cache configuration with both group names.
For instance, whenever a new post is added, we could tell the Cache engine to remove all entries associated to the article group:
// src/Model/Table/ArticlesTable.php
public function
afterSave ( $entity , $options = [])
{
if
( $entity -> isNew ()) {
Cache :: clearGroup ( 'article' , 'site_home' );
}
}
Using Cache to Store Common Query Results 491
CakePHP Cookbook Documentation, Release 3.x
static Cake\Cache\Cache::groupConfigs($group = null) groupConfigs() can be used to retrieve mapping between group and configurations, i.e.: having the same group:
// src/Model/Table/ArticlesTable.php
/**
* A variation of previous example that clears all Cache configurations
* having the same group
*/
public function
afterSave ( $entity , $options = [])
{
if
( $entity -> isNew ()) {
$configs = Cache :: groupConfigs ( 'article' );
foreach
( $configs [ 'article' ]
as
$config ) {
Cache :: clearGroup ( 'article' , $config );
}
}
}
Groups are shared across all cache configs using the same engine and same prefix. If you are using groups and want to take advantage of group deletion, choose a common prefix for all your configs.
Globally Enable or Disable Cache
static Cake\Cache\Cache::disable
You may need to disable all Cache read & writes when trying to figure out cache expiration related issues.
You can do this using enable() and disable():
// Disable all cache reads, and cache writes.
Cache :: disable ();
Once disabled, all reads and writes will return null.
static Cake\Cache\Cache::enable
Once disabled, you can use enable() to re-enable caching:
// Re-enable all cache reads, and cache writes.
Cache :: enable (); static Cake\Cache\Cache::enabled
If you need to check on the state of Cache, you can use enabled().
Creating a Storage Engine for Cache
You can provide custom Cache adapters in App\Cache\Engine as well as in plugins using
$plugin\Cache\Engine
.
src/plugin cache engines can also override the core engines.
Cache
492 Chapter 15. Caching
CakePHP Cookbook Documentation, Release 3.x
adapters must be in a cache directory. If you had a cache engine named MyCustomCacheEngine it would be placed in either src/Cache/Engine/MyCustomCacheEngine.php as an app/libs.
Or in
$plugin/Cache/Engine/MyCustomCacheEngine.php
as part of a plugin. Cache configs from plugins need to use the plugin dot syntax.
Cache :: config ( 'custom' , [
'className' => 'CachePack.MyCustomCache' ,
// ...
]);
Custom Cache engines must extend
Cake\Cache\CacheEngine
which defines a number of abstract methods as well as provides a few initialization methods.
The required API for a CacheEngine is class Cake\Cache\CacheEngine
The base class for all cache engines used with Cache.
Cake\Cache\CacheEngine::write(
$key , $value, $config = ‘default’)
Returns boolean for success.
Write value for a key into cache, optional string $config specifies configuration name to write to.
Cake\Cache\CacheEngine::read(
$key)
Returns The cached value or false for failure.
Read a key from the cache. Return false to indicate the entry has expired or does not exist.
Cake\Cache\CacheEngine::delete(
$key)
Returns Boolean true on success.
Delete a key from the cache. Return false to indicate that the entry did not exist or could not be deleted.
Cake\Cache\CacheEngine::clear(
$check)
Returns Boolean true on success.
Delete all keys from the cache. If $check is true, you should validate that each value is actually expired.
Cake\Cache\CacheEngine::clearGroup(
$group)
Returns Boolean true on success.
Delete all keys from the cache belonging to the same group.
Cake\Cache\CacheEngine::decrement(
$key , $offset = 1)
Returns Boolean true on success.
Decrement a number under the key and return decremented value
Cake\Cache\CacheEngine::increment(
$key , $offset = 1)
Returns Boolean true on success.
Creating a Storage Engine for Cache 493
CakePHP Cookbook Documentation, Release 3.x
Increment a number under the key and return incremented value
Cake\Cache\CacheEngine::gc()
Not required, but used to do clean up when resources expire. FileEngine uses this to delete files containing expired content.
494 Chapter 15. Caching
Download
Advertisement
Key features
Rapid Development
MVC Architecture
Database Abstraction
Security Features
Templating Engine
Built-in Components
Extensive Documentation
Active Community
Frequently asked questions
CakePHP is a free, open-source framework for PHP that provides a structured way to build web applications. It follows the Model-View-Controller (MVC) design pattern and offers a wide range of features to help you develop applications quickly and efficiently.
CakePHP offers many benefits, including: rapid development, code reusability, security features, and a large, active community. It helps you build reliable and scalable applications while minimizing the amount of code you have to write.
You can get started by installing CakePHP using Composer. Once installed, you can follow the instructions in the documentation to create a new CakePHP project and begin building your web application.