Files
yii/docs/guide/caching.page.txt
2012-07-13 17:11:18 +02:00

109 lines
4.6 KiB
Plaintext

Page Caching
============
Page caching refers to caching the content of a whole page. Page caching
can occur at different places. For example, by choosing an appropriate page
header, the client browser may cache the page being viewed for a limited
time. The Web application itself can also store the page content in cache.
Output Caching
--------------
Page caching can be considered as a special case of [fragment
caching](/doc/guide/caching.fragment). Because the content of a page is
often generated by applying a layout to a view, it will not work if we
simply call [beginCache()|CBaseController::beginCache] and
[endCache()|CBaseController::endCache] in the layout. The reason is because
the layout is applied within the [CController::render()] method AFTER the
content view is evaluated.
To cache a whole page, we should skip the execution of the action
generating the page content. We can use [COutputCache] as an action
[filter](/doc/guide/basics.controller#filter) to accomplish this task. The
following code shows how we configure the cache filter:
~~~
[php]
public function filters()
{
return array(
array(
'COutputCache',
'duration'=>100,
'varyByParam'=>array('id'),
),
);
}
~~~
The above filter configuration would make the filter to be applied to all
actions in the controller. We may limit it to one or a few actions only by
using the plus operator. More details can be found in
[filter](/doc/guide/basics.controller#filter).
> Tip: We can use [COutputCache] as a filter because it extends from
[CFilterWidget], which means it is both a widget and a filter. In fact, the
way a widget works is very similar to a filter: a widget (filter) begins
before any enclosed content (action) is evaluated, and the widget (filter)
ends after the enclosed content (action) is evaluated.
HTTP Caching
------------
In addition to simply caching the output of an action, Yii introduced
[CHttpCacheFilter] in version 1.1.11. This filter aids in setting the
aforementioned headers to notify a client that a page's content has not been
changed since the last request, so the server will not have to re-transmit the
content. [CHttpCacheFilter] can be set up similar to [COutputCache]:
~~~
[php]
public function filters()
{
return array(
array(
'CHttpCacheFilter + index',
'lastModified'=>Yii::app()->db->createCommand("SELECT MAX(`update_time`) FROM {{post}}")->queryScalar(),
),
);
}
~~~
The above code will set the `Last-Modified` header to the last date at which a
post was updated. You can also use [CHttpCacheFilter::lastModifiedExpression] to set
the `Last-Modified` header using a php expression.
> Tip: Both, [CHttpCacheFilter::lastModifiedExpression] and
[CHttpCacheFilter::lastModified] can take either an integer representing an
epochal Unix timestamp or an arbitrary string representing a human-readable
date. As long as later one can be parsed by
[strtotime()](http://php.net/manual/function.strtotime.php), no further
conversion is necessary.
The "Entity Tag" (or `ETag` for short) header can be set in a similar fashion
through [CHttpCacheFilter::etagSeed] and [CHttpCacheFilter::etagSeedExpression]
, respectively. Both will be serialized (so you can use either a single value
or an entire array) and are used to generate a quoted, base64-encoded SHA1
hash serving as content for the `ETag` header. This differs from the way the
[Apache Webserver](http://httpd.apache.org) and others are generating their
ETags. However, this method is perfectly in line with the RFC and turned out to
be more feasible for use in a framework.
> Note: In order to comply with
[RFC 2616, section 13.3.4](http://tools.ietf.org/html/rfc2616#section-13.3.4),
[CHttpCacheFilter] will send out `ETag` *and* `Last-Modified` headers if they
can both be generated. Consequently, both will be used for cache validation if
sent by the client.
Since entity tags are hashes, they allow more complex and/or more precise
caching strategies than `Last-Modified` headers. For instance, an ETag can be
invalidated if the site has switched to another theme.
> Tip: Expensive expressions for [CHttpCacheFilter::etagSeedExpression] may
defeat the purpose of [CHttpCacheFilter] and introduce unnecessary overhead,
since they need to be re-evaluated on every request. Try to find a simple
expression that invalidates the cache if the page *content* has been modified.
### SEO Implications
Search engine bots tend to respect cache headers. Since some crawlers have a
limit on how many pages per domain they process within a certain time span,
introducing caching headers may help indexing your site as they reduce the
number of pages that need to be processed.
<div class="revision">$Id$</div>