caching.md 9.88 KB
Newer Older
Alexander Makarov committed
1 2 3
Caching
=======

resurtm committed
4
Caching is a cheap and effective way to improve the performance of a web application. By storing relatively
Larry Ullman committed
5 6 7 8
static data in cache and serving it from cache when requested, the application saves the time required to generate the data from scratch. Caching is one of the best ways to improve the performance of your application, almost mandatory on any large-scale site.


Base Concepts
9
-------------
resurtm committed
10

Larry Ullman committed
11
Using cache in Yii involves configuring and accessing a cache application component. The following
resurtm committed
12
application configuration specifies a cache component that uses [memcached](http://memcached.org/) with
resurtm committed
13 14
two cache servers. Note, this configuration should be done in file located at `@app/config/web.php` alias
in case you're using basic sample application.
resurtm committed
15 16

```php
Alexander Makarov committed
17 18
'components' => [
	'cache' => [
resurtm committed
19
		'class' => '\yii\caching\MemCache',
Alexander Makarov committed
20 21
		'servers' => [
			[
resurtm committed
22 23 24
				'host' => 'server1',
				'port' => 11211,
				'weight' => 100,
Alexander Makarov committed
25 26
			],
			[
resurtm committed
27 28 29
				'host' => 'server2',
				'port' => 11211,
				'weight' => 50,
Alexander Makarov committed
30 31 32 33
			],
		],
	],
],
resurtm committed
34 35 36 37
```

When the application is running, the cache component can be accessed through `Yii::$app->cache` call.

resurtm committed
38 39
Yii provides various cache components that can store cached data in different media. The following
is a summary of the available cache components:
resurtm committed
40

41
* [[yii\caching\ApcCache]]: uses PHP [APC](http://php.net/manual/en/book.apc.php) extension. This option can be
resurtm committed
42 43 44
  considered as the fastest one when dealing with cache for a centralized thick application (e.g. one
  server, no dedicated load balancers, etc.).

45
* [[yii\caching\DbCache]]: uses a database table to store cached data. By default, it will create and use a
resurtm committed
46 47 48
  [SQLite3](http://sqlite.org/) database under the runtime directory. You can explicitly specify a database for
  it to use by setting its `db` property.

49
* [[yii\caching\DummyCache]]: presents dummy cache that does no caching at all. The purpose of this component
resurtm committed
50 51 52 53
  is to simplify the code that needs to check the availability of cache. For example, during development or if
  the server doesn't have actual cache support, we can use this cache component. When an actual cache support
  is enabled, we can switch to use the corresponding cache component. In both cases, we can use the same
  code `Yii::$app->cache->get($key)` to attempt retrieving a piece of data without worrying that
Carsten Brandt committed
54
  `Yii::$app->cache` might be `null`.
resurtm committed
55

56
* [[yii\caching\FileCache]]: uses standard files to store cached data. This is particular suitable
resurtm committed
57 58
  to cache large chunk of data (such as pages).

59
* [[yii\caching\MemCache]]: uses PHP [memcache](http://php.net/manual/en/book.memcache.php)
resurtm committed
60 61 62 63
  and [memcached](http://php.net/manual/en/book.memcached.php) extensions. This option can be considered as
  the fastest one when dealing with cache in a distributed applications (e.g. with several servers, load
  balancers, etc.)

64
* [[yii\redis\Cache]]: implements a cache component based on [Redis](http://redis.io/) key-value store
marsuboss committed
65
  (redis version 2.6.12 or higher is required).
resurtm committed
66

67
* [[yii\caching\WinCache]]: uses PHP [WinCache](http://iis.net/downloads/microsoft/wincache-extension)
resurtm committed
68 69
  ([see also](http://php.net/manual/en/book.wincache.php)) extension.

70
* [[yii\caching\XCache]]: uses PHP [XCache](http://xcache.lighttpd.net/) extension.
resurtm committed
71

72
* [[yii\caching\ZendDataCache]]: uses
resurtm committed
73 74 75
  [Zend Data Cache](http://files.zend.com/help/Zend-Server-6/zend-server.htm#data_cache_component.htm)
  as the underlying caching medium.

76
Tip: because all these cache components extend from the same base class [[yii\caching\Cache]], one can switch to use
resurtm committed
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
a different type of cache without modifying the code that uses cache.

Caching can be used at different levels. At the lowest level, we use cache to store a single piece of data,
such as a variable, and we call this data caching. At the next level, we store in cache a page fragment which
is generated by a portion of a view script. And at the highest level, we store a whole page in cache and serve
it from cache as needed.

In the next few subsections, we elaborate how to use cache at these levels.

Note, by definition, cache is a volatile storage medium. It does not ensure the existence of the cached
data even if it does not expire. Therefore, do not use cache as a persistent storage (e.g. do not use cache
to store session data or other valuable information).

Data Caching
------------

Data caching is about storing some PHP variable in cache and retrieving it later from cache. For this purpose,
94
the cache component base class [[yii\caching\Cache]] provides two methods that are used most of the time:
95
[[yii\caching\Cache::set()|set()]] and [[yii\caching\Cache::get()|get()]]. Note, only serializable variables and objects could be cached successfully.
resurtm committed
96

97
To store a variable `$value` in cache, we choose a unique `$key` and call [[yii\caching\Cache::set()|set()]] to store it:
resurtm committed
98 99 100 101 102 103 104

```php
Yii::$app->cache->set($key, $value);
```

The cached data will remain in the cache forever unless it is removed because of some caching policy
(e.g. caching space is full and the oldest data are removed). To change this behavior, we can also supply
105
an expiration parameter when calling [[yii\caching\Cache::set()|set()]] so that the data will be removed from the cache after
resurtm committed
106 107 108 109 110 111 112
a certain period of time:

```php
// keep the value in cache for at most 45 seconds
Yii::$app->cache->set($key, $value, 45);
```

113
Later when we need to access this variable (in either the same or a different web request), we call [[yii\caching\Cache::get()|get()]]
resurtm committed
114 115 116 117 118 119 120
with the key to retrieve it from cache. If the value returned is `false`, it means the value is not available
in cache and we should regenerate it:

```php
public function getCachedData()
{
	$key = /* generate unique key here */;
Carsten Brandt committed
121
	$value = Yii::$app->cache->get($key);
resurtm committed
122 123
	if ($value === false) {
		$value = /* regenerate value because it is not found in cache and then save it in cache for later use */;
lancecoder committed
124
		Yii::$app->cache->set($key, $value);
resurtm committed
125 126 127 128 129 130 131 132 133 134 135 136
	}
	return $value;
}
```

This is the common pattern of arbitrary data caching for general use.

When choosing the key for a variable to be cached, make sure the key is unique among all other variables that
may be cached in the application. It is **NOT** required that the key is unique across applications because
the cache component is intelligent enough to differentiate keys for different applications.

Some cache storages, such as MemCache, APC, support retrieving multiple cached values in a batch mode,
137
which may reduce the overhead involved in retrieving cached data. A method named [[yii\caching\Cache::mget()|mget()]] is provided
resurtm committed
138
to exploit this feature. In case the underlying cache storage does not support this feature,
139
[[yii\caching\Cache::mget()|mget()]] will still simulate it.
resurtm committed
140

141 142 143 144
To remove a cached value from cache, call [[yii\caching\Cache::delete()|delete()]]; and to remove everything from cache, call
[[yii\caching\Cache::flush()|flush()]].
Be very careful when calling [[yii\caching\Cache::flush()|flush()]] because it also removes cached data that are from
other applications if the cache is shared among different applications.
resurtm committed
145

146
Note, because [[yii\caching\Cache]] implements `ArrayAccess`, a cache component can be used liked an array. The followings
resurtm committed
147 148 149
are some examples:

```php
150
$cache = Yii::$app->cache;
resurtm committed
151 152 153 154 155 156
$cache['var1'] = $value1;  // equivalent to: $cache->set('var1', $value1);
$value2 = $cache['var2'];  // equivalent to: $value2 = $cache->get('var2');
```

### Cache Dependency

157 158 159 160
Besides expiration setting, cached data may also be invalidated according to some dependency changes. For example, if we
are caching the content of some file and the file is changed, we should invalidate the cached copy and read the latest
content from the file instead of the cache.

161
We represent a dependency as an instance of [[yii\caching\Dependency]] or its child class. We pass the dependency
162
instance along with the data to be cached when calling [[yii\caching\Cache::set()|set()]].
163 164

```php
165
use yii\caching\FileDependency;
166 167 168 169 170 171 172 173 174 175 176

// the value will expire in 30 seconds
// it may also be invalidated earlier if the dependent file is changed
Yii::$app->cache->set($id, $value, 30, new FileDependency(['fileName' => 'example.txt']));
```

Now if we retrieve $value from cache by calling `get()`, the dependency will be evaluated and if it is changed, we will
get a false value, indicating the data needs to be regenerated.

Below is a summary of the available cache dependencies:

177 178 179 180 181 182
- [[yii\caching\FileDependency]]: the dependency is changed if the file's last modification time is changed.
- [[yii\caching\GroupDependency]]: marks a cached data item with a group name. You may invalidate the cached data items
  with the same group name all at once by calling [[yii\caching\GroupDependency::invalidate()]].
- [[yii\caching\DbDependency]]: the dependency is changed if the query result of the specified SQL statement is changed.
- [[yii\caching\ChainedDependency]]: the dependency is changed if any of the dependencies on the chain is changed.
- [[yii\caching\ExpressionDependency]]: the dependency is changed if the result of the specified PHP expression is
183
  changed.
resurtm committed
184 185 186

### Query Caching

187 188 189 190 191 192 193 194 195
For caching the result of database queries you can wrap them in calls to [[yii\db\Connection::beginCache()]]
and [[yii\db\Connection::endCache()]]:

```php
$connection->beginCache(60); // cache all query results for 60 seconds.
// your db query code here...
$connection->endCache();
```

resurtm committed
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226

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

### HTTP Caching

TBD: http://www.yiiframework.com/doc/guide/1.1/en/caching.page#http-caching