Qiang Xue
10 years ago
9 changed files with 327 additions and 43 deletions
@ -1,30 +0,0 @@
|
||||
|
||||
|
||||
|
||||
Fragment Caching |
||||
---------------- |
||||
|
||||
TBD: http://www.yiiframework.com/doc/guide/1.1/en/caching.fragment |
||||
|
||||
### Caching Options |
||||
|
||||
TBD: http://www.yiiframework.com/doc/guide/1.1/en/caching.fragment#caching-options |
||||
|
||||
### Nested Caching |
||||
|
||||
TBD: http://www.yiiframework.com/doc/guide/1.1/en/caching.fragment#nested-caching |
||||
|
||||
Dynamic Content |
||||
--------------- |
||||
|
||||
TBD: http://www.yiiframework.com/doc/guide/1.1/en/caching.dynamic |
||||
|
||||
Page Caching |
||||
------------ |
||||
|
||||
TBD: http://www.yiiframework.com/doc/guide/1.1/en/caching.page |
||||
|
||||
### Output Caching |
||||
|
||||
TBD: http://www.yiiframework.com/doc/guide/1.1/en/caching.page#output-caching |
||||
|
@ -0,0 +1,176 @@
|
||||
Fragment Caching |
||||
================ |
||||
|
||||
Fragment caching refers to caching a fragment of a Web page. For example, if a page displays a summary of |
||||
yearly sale in a table, you can store this table in cache to eliminate the time needed to generate this table |
||||
for each request. Fragment caching is built on top of [data caching](caching-data.md). |
||||
|
||||
To use fragment caching, use the following construct in a [view](structure-views.md): |
||||
|
||||
```php |
||||
if ($this->beginCache($id)) { |
||||
|
||||
// ... generate content here ... |
||||
|
||||
$this->endCache(); |
||||
} |
||||
``` |
||||
|
||||
That is, enclose content generation logic in a pair of [[yii\base\View::beginCache()|beginCache()]] and |
||||
[[yii\base\View::endCache()|endCache()]] calls. If the content is found in the cache, [[yii\base\View::beginCache()|beginCache()]] |
||||
will render the cached content and return false, thus skip the content generation logic. |
||||
Otherwise, your content generation logic will be called, and when [[yii\base\View::endCache()|endCache()]] |
||||
is called, the generated content will be captured and stored in the cache. |
||||
|
||||
Like [data caching](caching-data.md), a unique `$id` is needed to identify a content cache. |
||||
|
||||
|
||||
## Caching Options <a name="caching-options"></a> |
||||
|
||||
You may specify additional options about fragment caching by passing the option array as the second |
||||
parameter to the [[yii\base\View::beginCache()|beginCache()]] method. Behind the scene, this option array |
||||
will be used to configure a [[yii\widgets\FragmentCache]] widget which implements the actual fragment caching |
||||
functionality. |
||||
|
||||
### Duration <a name="duration"></a> |
||||
|
||||
Perhaps the most commonly used option of fragment caching is [[yii\widgets\FragmentCache::duration|duration]]. |
||||
It specifies for how many seconds the content can remain valid in a cache. The following code |
||||
caches the content fragment for at most one hour: |
||||
|
||||
```php |
||||
if ($this->beginCache($id, ['duration' => 3600])) { |
||||
|
||||
// ... generate content here ... |
||||
|
||||
$this->endCache(); |
||||
} |
||||
``` |
||||
|
||||
If the option is not set, it will take the default value 0, which means the cached content will never expire. |
||||
|
||||
|
||||
### Dependencies <a name="dependencies"></a> |
||||
|
||||
Like [data caching](caching-data.md#cache-dependencies), content fragment being cached can also have dependencies. |
||||
For example, the content of a post being displayed depends on whether or not the post is modified. |
||||
|
||||
To specify a dependency, set the [[yii\widgets\FragmentCache::dependency|dependency]] option, which can be |
||||
either an [[yii\caching\Dependency]] object or a configuration array for creating a dependency object. The |
||||
following code specifies that the fragment content depends on the change of the `updated_at` column value: |
||||
|
||||
```php |
||||
$dependency = [ |
||||
'class' => 'yii\caching\DbDependency', |
||||
'sql' => 'SELECT MAX(updated_at) FROM post', |
||||
]; |
||||
|
||||
if ($this->beginCache($id, ['dependency' => $dependency])) { |
||||
|
||||
// ... generate content here ... |
||||
|
||||
$this->endCache(); |
||||
} |
||||
``` |
||||
|
||||
|
||||
### Variations <a name="variations"></a> |
||||
|
||||
Content being cached may be variated according to some parameters. For example, for a Web application |
||||
supporting multiple languages, the same piece of view code may generate the content in different languages. |
||||
Therefore, you may want to make the cached content variated according to the current application language. |
||||
|
||||
To specify cache variations, set the [[yii\widgets\FragmentCache::variations|variations]] option, which |
||||
should be an array of scalar values, each representing a particular variation factor. For example, |
||||
to make the cached content variated by the language, you may use the following code: |
||||
|
||||
```php |
||||
if ($this->beginCache($id, ['variations' => [Yii::$app->language]])) { |
||||
|
||||
// ... generate content here ... |
||||
|
||||
$this->endCache(); |
||||
} |
||||
``` |
||||
|
||||
|
||||
### Toggling Caching <a name="toggling-caching"></a> |
||||
|
||||
Sometimes you may want to enable fragment caching only when certain conditions are met. For example, for a page |
||||
displaying a form, you only want to cache the form when it is initially requested (via GET request). Any |
||||
subsequent display (via POST request) of the form should not be cached because the form may contain user input. |
||||
To do so, you may set the [[yii\widgets\FragmentCache::enabled|enabled]] option, like the following: |
||||
|
||||
```php |
||||
if ($this->beginCache($id, ['enabled' => Yii::$app->request->isGet])) { |
||||
|
||||
// ... generate content here ... |
||||
|
||||
$this->endCache(); |
||||
} |
||||
``` |
||||
|
||||
|
||||
## Nested Caching <a name="nested-caching"></a> |
||||
|
||||
Fragment caching can be nested. That is, a cached fragment can be enclosed within another fragment which is also cached. |
||||
For example, the comments are cached in an inner fragment cache, and they are cached together with the |
||||
post content in an outer fragment cache. The following code shows how two fragment caches can be nested: |
||||
|
||||
```php |
||||
if ($this->beginCache($id1)) { |
||||
|
||||
// ...content generation logic... |
||||
|
||||
if ($this->beginCache($id2, $options2)) { |
||||
|
||||
// ...content generation logic... |
||||
|
||||
$this->endCache(); |
||||
} |
||||
|
||||
// ...content generation logic... |
||||
|
||||
$this->endCache(); |
||||
} |
||||
``` |
||||
|
||||
Different caching options can be set for the nested caches. For example, the inner caches and the outer caches |
||||
can use different cache duration values. Even when the data cached in the outer cache is invalidated, the inner |
||||
cache may still provide the valid inner fragment. However, it is not true vice versa. If the outer cache is |
||||
evaluated to be valid, it will continue to provide the same cached copy even after the content in the |
||||
inner cache has been invalidated. Therefore, you must be careful in setting the durations or the dependencies |
||||
of the nested caches, otherwise the outdated inner fragments may be kept in the outer fragment. |
||||
|
||||
|
||||
## Dynamic Content <a name="dynamic-content"></a> |
||||
|
||||
When using fragment caching, you may encounter the situation where a large fragment of content is relatively |
||||
static except at one or a few places. For example, a page header may display the main menu bar together with |
||||
the name of the current user. Another problem is that the content being cached may contain PHP code that |
||||
must be executed for every request (e.g. the code for registering an asset bundle). Both problems can be solved |
||||
by the so-called *dynamic content* feature. |
||||
|
||||
A dynamic content means a fragment of output that should not be cached even if it is enclosed within |
||||
a fragment cache. To make the content dynamic all the time, it has to be generated by executing some PHP code |
||||
for every request, even if the enclosing content is being served from cache. |
||||
|
||||
You may call [[yii\base\View::renderDynamic()]] within a cached fragment to insert dynamic content |
||||
at the desired place, like the following, |
||||
|
||||
```php |
||||
if ($this->beginCache($id1)) { |
||||
|
||||
// ...content generation logic... |
||||
|
||||
echo $this->renderDynamic('return Yii::$app->user->identity->name;'); |
||||
|
||||
// ...content generation logic... |
||||
|
||||
$this->endCache(); |
||||
} |
||||
``` |
||||
|
||||
The [[yii\base\View::renderDynamic()|renderDynamic()]] method takes a piece of PHP code as its parameter. |
||||
The return value of the PHP code is treated as the dynamic content. The same PHP code will be executed |
||||
for every request, no matter the enclosing fragment is being served from cached or not. |
@ -0,0 +1,40 @@
|
||||
Page Caching |
||||
============ |
||||
|
||||
Page caching refers to caching the content of a whole page on the server side. Later when the same page |
||||
is requested again, its content will be served from the cache instead of regenerating it from scratch. |
||||
|
||||
Page caching is supported by [[yii\filters\PageCache]], an [action filter](runtime-filtering.md). |
||||
It can be used like the following in a controller class: |
||||
|
||||
```php |
||||
public function behaviors() |
||||
{ |
||||
return [ |
||||
[ |
||||
'class' => 'yii\filters\PageCache', |
||||
'only' => ['index'], |
||||
'duration' => 60, |
||||
'variations' => [ |
||||
\Yii::$app->language, |
||||
], |
||||
'dependency' => [ |
||||
'class' => 'yii\caching\DbDependency', |
||||
'sql' => 'SELECT COUNT(*) FROM post', |
||||
], |
||||
], |
||||
]; |
||||
} |
||||
``` |
||||
|
||||
The above code states that page caching should be used only for the `index` action; the page content should |
||||
be cached for at most 60 seconds and should be variated by the current application language; |
||||
and the cached page should be invalidated if the total number of posts is changed. |
||||
|
||||
As you can see, page caching is very similar to [fragment caching](caching-fragment.md). They both support options such |
||||
as `duration`, `dependencies`, `variations`, and `enabled`. Their main difference is that page caching is |
||||
implemented as an [action filter](runtime-filtering.md) while fragment caching a [widget](structure-widgets.md). |
||||
|
||||
You can use [fragment caching](caching-fragment.md) as well as [dynamic content](caching-fragment.md#dynamic-content) |
||||
together with page caching. |
||||
|
Loading…
Reference in new issue