Deep parsing of the caching features in the YII framework of PHP _php tips

Source: Internet
Author: User
Tags apc memcached redis scalar yii

Data caching refers to storing some PHP variables in the cache and retrieving them from the cache when used. It is also the basis for more advanced caching features, such as query caching and content caching.

The following code is a typical data caching usage pattern. Where $cache point to the cache component:

Attempt to retrieve $data $data from the cache 
= $cache->get ($key);

if ($data = = False) {

  //$data not found in cache, recalculate its value

  //store $data to cache for next use
  $cache->set ($key, $data);
}

//Here $data can be used.

Cache components

Data caching requires support from the cache component, which represents a variety of cache memory, such as memory, files, and databases.

Cache components are typically registered as application components so that they can be configured and accessed globally. The following code demonstrates how to configure an application component cache uses two memcached servers:

' Components ' => ['
  cache ' => ['
    class ' => ' Yii\caching\memcache ',
    ' servers ' =>
      ' [
        ' host ' => ' Server1 ',
        ' Port ' => 11211,
        ' weight ' =>,
      ],
      [
        ' Host ' => ' Server2 ',
        ' Port ' => 11211,
        ' weight ' =>,
      ]
,],

You can then access the above cache component via Yii:: $app->cache.

Since all cache components support the same series of APIs, it is not necessary to modify the business code that uses the cache to replace it directly with other underlying cache components, simply by reconfiguring it in the 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, and many classes that rely on caching call a component named cache (for example, Yii\web\urlmanager) by default.
Supported cache memory

YII supports a series of cache memory, as follows:

    • Yii\caching\apccache: Using the PHP APC extension. This option can be considered the fastest caching scheme in a centralized application environment (for example, a single server, no independent load balancer, and so on).
    • Yii\caching\dbcache: Use a table of a database to store cached data. To use this cache, you must create a table corresponding to the yii\caching\dbcache::cachetable.
    • Yii\caching\dummycache: As only a cache placeholder, does not implement any true caching functionality. The purpose of this component is to simplify the code that requires query caching validity. For example, in development, if the server does not have actual cache support, use it to configure a cache component. Once a real caching service is enabled, you can switch to using the appropriate cache component. Both conditions you can use the same code Yii:: $app->cache->get ($key) Try to retrieve the data from the cache without worrying about YII:: $app->cache may be null.
    • Yii\caching\filecache: Cache data is stored using standard files. This is especially useful for caching large chunks of data, such as the contents of an entire page.
    • Yii\caching\memcache: Use PHP MemCache and memcached extensions. This option is considered as the fastest caching scheme in a distributed application environment (for example, multiple servers, load balancing, and so on).
    • Yii\redis\cache: Implements a cache component based on Redis key value pairs of memory (requires support for Redis 2.6.12 and above versions).
    • Yii\caching\wincache: Use PHP Wincache (other reference) to extend.
    • Yii\caching\xcache: Extensions using PHP XCache.
    • Yii\caching\zenddatacache: Use the Zend Data cache as the underlying caching medium.
    • Tip: You can use a different cache memory in the same application. A common strategy is to use memory-based cache memory to store small, commonly used data, such as statistics, and to store large, infrequently used data (for example, Web content) using a file-based or database-based cache memory.

Caching APIs

All cache components have the same base class Yii\caching\cache, so the following APIs are supported:

    • Yii\caching\cache::get (): Retrieves a piece of data from the cache through a specified key. If the item data does not exist in the cache or is expired/invalidated, the return value is false.
    • Yii\caching\cache::set (): Specify a key for the data to be stored 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 (): Retrieving multiple data from the cache with a specified number of keys.
    • Yii\caching\cache::mset (): Stores multiple data in a cache with one key for each data.
    • Yii\caching\cache::madd (): Stores multiple data in a cache with one key for each data. If a key already exists in the cache, the item data is skipped.
    • Yii\caching\cache::exists (): Returns a value indicating whether a key exists in the cache.
    • Yii\caching\cache::d elete (): Deletes the corresponding value in the cache by a key.
    • Yii\caching\cache::flush (): Deletes all data in the cache.
    • Some cache memory such as MEMCACHE,APC support to retrieve cached values in bulk mode, which saves the expense of retrieving cached data. The 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 also simulates the implementation.

Because Yii\caching\cache implements the PHP Arrayaccess interface, the cache component can also be used as an array, and here are a few examples:

$cache [' var1 '] = $value 1; Equivalent to: $cache->set (' var1 ', $value 1);
$value 2 = $cache [' var2 ']; Equivalent to: $value 2 = $cache->get (' var2 ');

Cache key

Each data stored in the cache is uniquely identified by the key. When you store a data in the cache, you must specify a key for it, and you will need to provide the corresponding key when retrieving the data from the cache later.

You can use a string or any value as a caching key. When a key is not a string, it is automatically serialized as a string.

A common strategy for defining a cache key is to include all the determining factors in an array. For example, Yii\db\schema uses the following key to store the structure information of a data table.

[
  __class__,//       struct class name
  $this->db->dsn,     //Data source name
  $this->db->username,  // Database login user name
  $name,         //table name
];

As you can see, this key contains all the necessary information you need to uniquely specify a database table.

When the same cache memory is used for many different applications, you should specify a unique cache key prefix for each application to avoid caching key conflicts. Can be implemented by configuring the Yii\caching\cache::keyprefix property. For example, the following code can be written in the application configuration:

' Components ' => ['
  cache ' => ['
    class ' => ' Yii\caching\apccache ',
    ' keyprefix    ' => ' MyApp ', Unique key prefix
  ],
],

To ensure interoperability, only letters and numbers can be used here.

Cache Expiration

By default, the data in the cache is persisted until it is forcibly removed by some caching policies (for example, the cache space is full and the oldest data is removed). To change this attribute, you can provide an expiration time parameter when you call Yii\caching\cache::set () to store a data. This parameter represents how many seconds the data can remain in the cache. When you call Yii\caching\cache::get () to retrieve the data, if it has passed the timeout, the method returns False, indicating that the data is not found in the cache. For example:

Keep data in cache for 45 seconds
$cache->set ($key, $data,);

Sleep (m);

$data = $cache->get ($key);
if ($data = = False) {
  //$data has expired, or cannot be found in cache
}

Cache dependencies

In addition to the timeout setting, cached data may be invalidated by the effects of cache dependencies. For example, Yii\caching\filedependency represents a dependency on the time a file was modified. The change in the dependency condition means that the corresponding file has been modified. Therefore, any expired file contents in the cache should be set to a failed state, and calls to Yii\caching\cache::get () should return false.

Cache dependencies are represented by yii\caching\dependency derived classes. When a call to Yii\caching\cache::set () stores a data in the cache, an associated cache-dependent object can be passed at the same time. For example:

Create a cache dependency on the Example.txt file modification time
$dependency = new \yii\caching\filedependency ([' FileName ' => ' example.txt ']); c2/>//cached data will timeout after 30 seconds
//If Example.txt is modified, it may also be placed in an earlier failure state.
$cache->set ($key, $data, $dependency);

The cache checks to see if the data has timed out.
//It also checks whether the associated dependencies have changed.
//The return of false if any one of the conditions is met.
$data = $cache->get ($key);

The following is an overview of the available cache dependencies:

    • Yii\caching\chaineddependency: If any dependency on the dependency chain changes, it depends on the change.
    • Yii\caching\dbdependency: If the query result of the specified SQL statement changes, it depends on the change.
    • Yii\caching\expressiondependency: If the specified PHP expression has a change in execution, it depends on the change.
    • Yii\caching\filedependency: If the file's last modification time changes, it depends on the change.
    • Yii\caching\groupdependency: To mark a cached data to a group name, you can set the cache of the same group name to the failed state at once by calling Yii\caching\groupdependency::invalidate ().

Query caching

Query caching is a special caching feature that is built on top of the data cache. It is used to cache the results of a database query.

Query caching requires a yii\db\connection and a valid cache application component. The basic usage of query caching is as follows, assuming $db is a yii\db\connection instance:

$duration =;   Cached query results 60 seconds
$dependency = ...;//optional cache dependency

$db->begincache ($duration, $dependency);

// ... Execute database query

here ... $db->endcache ();

As you can see, any query results in the middle of Begincache () and Endcache () are cached. If the results of the same query are found in the cache, the query is skipped and the results are extracted directly from the cache.

Query caching can be used for ActiveRecord and DAO.

Info: Some DBMS (for example, MySQL) also support query caching on the database server side. You can choose to use any of the query caching mechanisms. The benefit of the query cache described above is that you can specify more flexible cache dependencies and therefore may be more efficient.
Configuration

The query cache has two configuration items that are set through Yii\db\connection:

Yii\db\connection::querycacheduration: The validity period of the query result in the cache, expressed in seconds. If an explicit value parameter is passed when Yii\db\connection::begincache () is invoked, the expiration value in the configuration is overwritten.
Yii\db\connection::querycache: The ID of the cache application component. Default is ' cache '. The query cache is valid only if a valid cache application component is set.
Restrictive conditions

The query cache cannot be used when the query result contains a resource handle. For example, when a BLOB column is used in some DBMS, the cached result returns a resource handle for that data column.

Some cache memory has a size limit. For example, memcache limits the maximum 1MB per piece of data. Therefore, if the size of the query result exceeds this limit, the cache will fail.

Fragment caching

Fragment caching refers to caching a fragment in a page's content. For example, a page displays a summary table of yearly sales, which can be cached to eliminate the time-consuming need to regenerate the table for each request. Fragment caching is implemented based on data caching.

Use the following structure in the view to enable fragment caching:

if ($this->begincache ($id)) {

  //... Generate content here ...

  $this->endcache ();
}

Call the Yii\base\view::begincache () and Yii\base\view::endcache () methods to wrap the content generation logic. If the content exists in the cache, the Yii\base\view::begincache () method renders the content and returns false, so the content generation logic is skipped. Otherwise, the content generation logic is executed until the Yii\base\view::endcache () is executed, and the generated content is captured and stored in the cache.

As with the data cache, each fragment cache requires a globally unique $id tag.

Caching options

If you want to specify additional configuration entries for the fragment cache, pass the configuration array by the second parameter to the Yii\base\view::begincache () method. Inside the frame, the array is used to configure a Yii\widget\fragmentcache widget to implement the fragment caching function.

Expiration Time (duration)

Perhaps one of the most common configuration options in fragment caching is Yii\widgets\fragmentcache::d uration. It specifies the number of seconds the content is cached. The following code caches content for up to one hour:

if ($this->begincache ($id, [' Duration ' => 3600])) {

  //... Generate content here ...

  $this->endcache ();
}

If this option is not set, the default is 0 and never expires.

Depend on

As with the data cache, the contents of the fragment cache can be set to cache dependencies. For example, a cached article is cached, depending on whether it has been modified or not.

By setting the Yii\widgets\fragmentcache::d ependency option to specify dependencies, the value of this option can be either a derived class of a yii\caching\dependency class or a configuration array that creates a cached object. The following code specifies a fragment cache that 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])) {

  //... Generate content here ...

  $this->endcache ();
}

Change

The contents of the cache may need to change depending on some parameter changes. For example, a WEB application supports multiple languages, and the same view code may need to generate content from multiple languages. Therefore, you can set the cache to vary according to the current language applied.

By setting the Yii\widgets\fragmentcache::variations option to specify the change, the value of the option should be a scalar, with each scalar representing a different coefficient of variation. For example, the settings cache varies according to the current language and can be used in the following code:

if ($this->begincache ($id, [' Variations ' => [Yii:: $app->language]]) {

  //... Generate content here ...

  $this->endcache ();
}

Switch

Sometimes you may want to open the fragment cache only under certain conditions. For example, a page that displays a form may only need to cache the form (through a GET request) on the first request. A form that is subsequently requested to display (through a POST request) should not use caching because the form may contain user input. In this case, you can use the yii\widgets\fragmentcache::enabled option to specify the caching switch, as follows:

if ($this->begincache ($id, [' Enabled ' => Yii:: $app->request->isget])) {

  //... Generate content here ...

  $this->endcache ();
}

Cache nesting

Fragment caching can be used in nested nesting. One fragment cache can be wrapped by another. For example, comments are cached in the inner layer, while fragments of the entire comment are cached in the outer layers of the article. The following code shows the nesting use of fragment caching:

if ($this->begincache ($id 1)) {

  //... Generate content here ...

  if ($this->begincache ($id 2, $options 2)) {

    //... Generate content here ...

    $this->endcache ();
  }

  // ... Generate content here ...

  $this->endcache ();
}

You can set different configuration items for nested caches. For example, the inner-layer cache and the outer cache use different expiration times. Even when the data in the outer cache expires, the inner cache may still provide a valid fragment cache data. But, conversely, otherwise. If the outer fragment cache is not expired and is considered valid, it will continue to provide the same cached copy even if the inner fragment cache is invalidated. Therefore, you must carefully handle the expiration time and dependencies in the cache nesting, otherwise the outer fragment is likely to return the failure data that does not meet your expectations.

The outer layer's expiration time should be shorter than the inner layers, and the outer dependencies should be lower than the inner layer to ensure that the smallest fragment returns the latest data.
Dynamic Content

When you use fragment caching, you may experience a situation where there is little dynamic content in a large section of the more static content. For example, a page header that displays the menu bar and current user name. Another possibility is that the cached content may contain PHP code (such as the code that registers the resource bundle) that needs to be executed for each request. Both of these issues can be resolved using dynamic content features.

Dynamic content means that the content of this part of the output should not be cached, even if it is wrapped in a fragment cache. To keep content dynamic, each request executes PHP code generation, even if the code is already cached.

You can invoke Yii\base\view::renderdynamic () in the fragment cache to insert dynamic content, as follows:

if ($this->begincache ($id 1)) {

  //... Generate content here ...

  echo $this->renderdynamic (' Return Yii:: $app->user->identity->name; ');

  // ... Generate content here ...

  $this->endcache ();
}

The Yii\base\view::renderdynamic () method accepts a section of PHP code as a parameter. The return value of the code is treated as dynamic content. This code will be executed on every request, regardless of whether the outer fragment cache is stored.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.