This article mainly introduces the caching function in PHP's Yii Framework. as a heavyweight framework pursuing high standards, Yii has a rich array of cache storage and APIs, for more information about data caching, you can store some PHP variables in the cache and retrieve them from the cache. It is also the basis for more advanced cache features, such as query cache and content cache.
The following code is a typical data cache usage mode. $ Cache points to the cache component:
// Try to retrieve $ data = $ cache-> get ($ key); if ($ data = false) from the cache) {// $ data is not found in the cache, then recalculate its value // store $ data in the cache for the next use $ cache-> set ($ key, $ data) ;}// $ data can be used here.
Cache component
Data Caching requires the support of the cache component, which represents various cache memories, such as memory, files, and databases.
Cache components are usually registered as application components so that they can be configured and accessed globally. The following code demonstrates how to configure the application component cache to use two memcached servers:
'components' => [ 'cache' => [ 'class' => 'yii\caching\MemCache', 'servers' => [ [ 'host' => 'server1', 'port' => 11211, 'weight' => 100, ], [ 'host' => 'server2', 'port' => 11211, 'weight' => 50, ], ], ],],
Then you can access the above cache components through Yii: $ app-> cache.
Because all cache components support the same series of APIs, you do not need to modify the business code that uses the cache to directly replace it with other underlying cache components. you only need to reconfigure it in application configuration. For example, you can modify the above configuration to use yii \ caching \ ApcCache:
'components' => [ 'cache' => [ 'class' => 'yii\caching\ApcCache', ],],
Tip: You can register multiple cache components. many dependent cache classes call the components named cache by default (for example, yii \ web \ UrlManager ).
Supported cache storage
Yii supports a series of cache storage, which is summarized as follows:
- Yii \ caching \ ApcCache: use php apc extension. This option can be considered as the fastest cache solution in a centralized application environment (for example, a single server without an independent server load balancer.
- Yii \ caching \ DbCache: uses a database table to store cached data. To use this cache, you must create a table corresponding to yii \ caching \ DbCache: cacheTable.
- Yii \ caching \ DummyCache: it is only used as a cache placeholder and does not implement any real cache function. This component aims to simplify the code that needs to query the cache validity. For example, if the server does not actually support caching during development, use it to configure a caching component. After a real cache service is enabled, you can switch to the corresponding cache component. In both cases, you can use the same code Yii: $ app-> cache-> get ($ key) to retrieve data from the cache without worrying about Yii :: $ app-> cache may be null.
- Yii \ caching \ FileCache: uses standard files to store cached data. This is especially suitable for caching large volumes of data, such as a whole page.
- Yii \ caching \ MemCache: use PHP memcache and memcached extensions. This option is considered as the fastest cache solution in a distributed application environment (for example, multiple servers and server load balancer.
- Yii \ redis \ Cache: implements a Cache component based on Redis key-value pair memory (redis 2.6.12 and later versions are required ).
- Yii \ caching \ WinCache: use PHP WinCache (For more information, see) extension.
- Yii \ caching \ XCache: use PHP XCache extension.
- Yii \ caching \ ZendDataCache: use Zend Data Cache as the underlying Cache medium.
- Tip: you can use different cache storages in the same application. A common strategy is to use memory-based cache storage to store small and commonly used data (for example, statistical data ), use cached files or databases to store large and infrequently used data (for example, webpage content ).
Cache API
All Cache components have the same base class yii \ caching \ Cache, so the following APIs are supported:
- Yii \ caching \ Cache: get (): retrieves data from the Cache using a specified key. If the data does not exist in the cache or has expired/expired, the return value is false.
- Yii \ caching \ Cache: set (): specifies a key for storing data in the Cache.
- Yii \ caching \ Cache: add (): If the key is not found in the Cache, the specified data is stored in the Cache.
- Yii \ caching \ Cache: mget (): retrieves multiple pieces of data from the Cache by specifying multiple keys.
- Yii \ caching \ Cache: mset (): stores multiple pieces of data in the Cache. each item corresponds to a key.
- Yii \ caching \ Cache: madd (): stores multiple pieces of data in the Cache. each item corresponds to a key. If a key already exists in the cache, the data is skipped.
- Yii \ caching \ Cache: exists (): returns a value indicating whether a key exists in the Cache.
- Yii \ caching \ Cache: delete (): deletes the value in the Cache with a key.
- Yii \ caching \ Cache: flush (): delete all data in the Cache.
- For some cache storages such as MemCache, APC supports retrieving cache values in batch mode, which can save the cost of retrieving cache data. Yii \ caching \ Cache: mget () and yii \ caching \ Cache: madd () APIs provide support for this feature. If the underlying cache memory does not support this feature, Yii will also simulate the implementation.
Because yii \ caching \ Cache implements the PHP ArrayAccess interface, the Cache component can also be used as an array. The following are several examples:
$ Cache ['var1'] = $ value1; // equivalent to: $ cache-> set ('var1', $ value1 ); $ value2 = $ cache ['var2']; // equivalent to: $ value2 = $ cache-> get ('var2 ');
Cache key
Each data item stored in the cache is uniquely identified by a key. When you store a data item in the cache, you must specify a key for it. when you retrieve data from the cache later, you also need to provide the corresponding key.
You can use a string or any value as a cache key. When a key is not a string, it is automatically serialized as a string.
A common policy for defining a cache key is to include all the decisive factors in an array. For example, yii \ db \ Schema uses the following key to store the structure information of a data table.
[_ CLASS __, // Structure CLASS name $ this-> db-> dsn, // Data Source name $ this-> db-> username, // database login username $ name, // table name];
As you can see, this key contains all the necessary information required to uniquely specify a database table.
When the same cache memory is used for multiple different applications, you should specify a unique cache key prefix for each application to avoid cache key conflicts. You can configure the yii \ caching \ Cache: keyPrefix attribute. For example, you can write the following code in application configuration:
'Components' => ['cache' => ['class' => 'yii \ caching \ apccache', 'keyprefix' => 'myapp ', // unique key prefix],],
To ensure interoperability, only letters and numbers are allowed here.
Cache expiration
By default, data in the cache is permanently stored unless it is forcibly removed by some cache policies (for example, when the cache space is full, the oldest data will be removed ). To change this feature, you can provide an expiration time parameter when calling yii \ caching \ Cache: set () to store a data item. This parameter indicates how many seconds the data can be kept valid in the cache. When you call yii \ caching \ Cache: get () to retrieve data, if it has expired, this method returns false, indicating that the data cannot be found in the Cache. For example:
// Keep the data in the cache for 45 seconds $ cache-> set ($ key, $ data, 45); sleep (50 ); $ data = $ cache-> get ($ key); if ($ data = false) {// $ data has expired or cannot be found in the cache}
Cache dependency
In addition to timeout settings, cached data may also become invalid due to the impact of cache dependencies. For example, yii \ caching \ FileDependency indicates the dependency on the modification time of a file. If the dependency condition changes, the corresponding file has been modified. Therefore, any expired file content in the Cache should be set to invalid, and false should be returned for calls to yii \ caching \ Cache: get.
The cache Dependency is represented by a derived class of yii \ caching \ Dependency. When yii \ caching \ Cache: set () is called to store a data item in the Cache, an associated Cache dependent object can be passed at the same time. For example:
// Create a cache dependency for the example.txt file modification time $ dependency = new \ yii \ caching \ FileDependency (['filename' => 'example.txt ']); // The cached data will time out after 30 seconds // If example.txt is modified, it may also be set to invalid earlier. $ Cache-> set ($ key, $ data, 30, $ dependency); // The cache checks whether the data has timed out. // It also checks whether the associated dependencies have changed. // If any condition is met, false is returned. $ Data = $ cache-> get ($ key );
The following is an overview of available cache dependencies:
- Yii \ caching \ ChainedDependency: If any dependency on the dependency chain changes, the dependency changes.
- Yii \ caching \ DbDependency: if the query result of the specified SQL statement changes, the dependency changes.
- Yii \ caching \ ExpressionDependency: If the execution result of the specified PHP expression changes, the dependency changes.
- Yii \ caching \ FileDependency: If the last modification time of the file changes, the dependency changes.
- Yii \ caching \ GroupDependency: Mark a cached data item to a group name. you can call yii \ caching \ GroupDependency: invalidate () set all the caches with the same group name to invalid at one time.
Query cache
Query cache is a special cache feature built on the data cache. It is used to cache the results of database queries.
A yii \ db \ Connection and a valid cache application component are required to query the cache. The basic usage of the query cache is as follows. Suppose $ db is a yii \ db \ Connection instance:
$ Duration = 60; // cache query result 60 seconds $ dependency = ...; // optional cache dependency $ db-> beginCache ($ duration, $ dependency );//... run the database query here... $ db-> endCache ();
As you can see, any query results between beginCache () and endCache () will be cached. If the same query result is found in the cache, the query is skipped and the result is extracted directly from the cache.
The query cache can be used for ActiveRecord and DAO.
Info: some DBMS (such as MySQL) also supports query cache on the database server. You can choose to use any query cache mechanism. The advantage of the query cache described above is that you can specify more flexible cache dependencies, which may be more efficient.
Configuration
The query cache has two configuration items set through yii \ db \ Connection:
Yii \ db \ Connection: queryCacheDuration: The validity period of the query result in the cache, in seconds. If an explicit value parameter is passed when yii \ db \ Connection: beginCache () is called, the validity period in the configuration will be overwritten.
Yii \ db \ Connection: queryCache: ID of the cache application component. The default value is 'cache '. The query cache is valid only when a valid cache application component is set.
Restrictions
When the query result contains a resource handle, the query cache cannot be used. For example, when BLOB columns are used in some DBMS, the cache results will return a resource handle for the data column.
Some cache storage has a size limit. For example, memcache limits the maximum size of each piece of data to 1 MB. Therefore, if the size of the query results exceeds this limit, the cache will fail.
Fragment cache
Fragment caching refers to a part of the cached page content. For example, if a summary table showing annual sales volume is displayed, you can cache the table to eliminate the time required to regenerate the table for each request. Fragment caching is implemented based on data caching.
Enable fragment caching using the following structure in the view:
If ($ this-> beginCache ($ id) {//... content generated here... $ this-> endCache ();}
Call the packaging content generation logic of the yii \ base \ View: beginCache () and yii \ base \ View: endCache () methods. If this content exists in the cache, the yii \ base \ View: beginCache () method renders the content and returns false. Therefore, the content generation logic is skipped. Otherwise, the content generation logic is executed. when yii \ base \ View: endCache () is executed, the generated content is captured and stored in the cache.
Like [data cache], each segment cache also requires a globally unique $ id mark.
Cache options
To specify additional configuration items for the fragment cache, pass the configuration array to the second parameter of the yii \ base \ View: beginCache () method. Within the framework, this array is used to configure a yii \ widget \ FragmentCache widget to implement the fragment cache function.
Duration)
Perhaps the most common configuration option in FragmentCache is yii \ widgets \ FragmentCache: duration. It specifies the number of seconds for the content to be cached. The following code caches a maximum of one hour:
If ($ this-> beginCache ($ id, ['duration' => 3600]) {//... content generated here... $ this-> endCache ();}
If this option is not set, the default value is 0 and it never expires.
Dependency
Like [data cache], cache dependencies can be set for the content cached by fragments. For example, whether a cached article is recached depends on whether it has been modified.
You can set the yii \ widgets \ FragmentCache: dependency option to specify dependencies. The value of this option can be a derived class of the yii \ caching \ Dependency class, it can also be a configuration array for creating cache objects. The following code specifies a fragment cache, which depends on whether the update_at field has been changed.
$ Dependency = ['class' => 'yii \ caching \ DbDependency ',' SQL '=> 'Select MAX (updated_at) FROM Post',]; if ($ this-> beginCache ($ id, ['dependency '=> $ dependency]) {//... content generated here... $ this-> endCache ();}
Change
The cached content may vary according to some parameter changes. For example, if a Web application supports multiple languages, the same view code may need to generate content in multiple languages. Therefore, you can set the cache to change according to the current language of the application.
You can set the yii \ widgets \ FragmentCache: variations option to specify the change. The value of this option is a scalar, and each scalar represents a different coefficient of variation. For example, you can use the following code to set the cache to change according to the current language:
If ($ this-> beginCache ($ id, ['Variations '=> [Yii: $ app-> language]) {//... content generated here... $ this-> endCache ();}
Switch
Sometimes you may only want to enable fragment caching under certain conditions. For example, a page displaying a form may only need to cache the form (via GET request) at the first request ). The form displayed in the request (via POST request) should not be cached, because the form may contain user input content. In this case, you can use the yii \ widgets \ FragmentCache: enabled option to specify the cache switch, as shown below:
If ($ this-> beginCache ($ id, ['enabled' => Yii: $ app-> request-> isGet]) {//... content generated here... $ this-> endCache ();}
Cache nesting
Fragment caching can be nested. One segment cache can be wrapped by another package. For example, the comment is cached in the layer, and the entire comment segment is cached in the outer article. The following code shows the nested usage of the fragment cache:
If ($ this-> beginCache ($ id1 )){//... content generated here... if ($ this-> beginCache ($ id2, $ options2 )){//... content generated here... $ this-> endCache ();}//... content generated here... $ this-> endCache ();}
You can set different configuration items for the nested cache. For example, the inner cache and the outer cache use different expiration times. Even if the data in the outer cache expires, the inner cache may still provide valid fragment cache data. However, otherwise. If the outer fragment cache does not expire and is considered valid, it will continue to provide the same cached copy even if the inner fragment cache has expired. Therefore, you must be cautious about the Expiration Time and dependency in the cache nesting. Otherwise, the outer part may return invalid data that does not meet your expectation.
Note: The validity period of the outer layer should be shorter than that of the inner layer, and the dependency condition of the outer layer should be lower than that of the inner layer to ensure that the latest data is returned for the smallest part.
Dynamic Content
When using fragment caching, a large segment of static content may contain a little dynamic content. For example, a page header that displays the menu bar and the current user name. Another possibility is that the cached content may contain the PHP code to be executed for each request (for example, the code for registering a resource package ). Both issues can be solved using the dynamic content function.
Dynamic content means that the output content should not be cached, even if it is wrapped in the clip cache. To keep the content dynamic, PHP code is executed for each request, even if the code has been cached.
You can call yii \ base \ View: renderDynamic () in the fragment cache to insert dynamic content, as shown below:
If ($ this-> beginCache ($ id1 )){//... content generated here... echo $ this-> renderDynamic ('return Yii: $ app-> user-> identity-> name ;');//... content generated here... $ this-> endCache ();}
The yii \ base \ View: renderDynamic () method accepts a piece of PHP code as a parameter. The return value of the code is regarded as dynamic content. This code will be executed during each request, regardless of whether the outer segment cache is stored.