「コントローラでキャッシュする」指定方法が変更になっている?

CakePHPでは、アクション単位でキャッシュ有無の指定を行うことが出来ます。

その場合、

var $cacheAction = array(
	'view/23/' => 21600,
	'view/48/' => 36000,
	'view/52'  => 48000
);

などのように記載するよう、解説されていますが、
これはver1.2までの仕様であり、1.3では変更になったようです。


http://book.cakephp.org/ja/view/1561/Migrating-from-CakePHP-1-2-to-1-3 等を読んでも、明確にそうは書いてないので、わかりずらいですが・・・



$cacheActionの指定で、キャッシュするかどうかを判断する処理は、ver.1.3で以下の通り。

cake/libs/views/cache.php

function cache($file, $out, $cache = false) {
	$cacheTime = 0;
	$useCallbacks = false;
	if (is_array($this->cacheAction)) {
		$keys = array_keys($this->cacheAction);
		$index = null;

		foreach ($keys as $action) {
			if ($action == $this->params['action']) {
				$index = $action;
				break;
			}
		}

		if (!isset($index) && $this->action == 'index') {
			$index = 'index';
		}
(後略)

$this->cacheActionのアクション指定($action)と、$this->params['action']が一致する場合、キャッシュ設定を行う内容です。

しかし、$this->params['action'] とは、アクション名のみであり、そこに IDやその他パラメータを含むことはありません。


したがって、

var $cacheAction = array(
	'view/23/' => 21600,
);

の設定では、
$action = 'view/23'
$this->params['action'] = 'view'
ですから、これらがマッチすることはありません。

var $cacheAction = array(
	'archives/' => '60000'
);

も、同様です。


ただし、

var $cacheAction = array(
	'view' => 21600,
);

と、設定すると、ver1.2にて'view/'と設定した場合と同様に、
IDやその他パラメータに関わらず、view/以下は全て、それぞれ別々にキャッシュされるようになります。


ver1.2時点のこの箇所のソースを見ると、スラッシュ以下の設定をマッチさせるために、複雑な処理を行っています。

function cache($file, $out, $cache = false) {
	$cacheTime = 0;
	$useCallbacks = false;
	if (is_array($this->cacheAction)) {
		$contoller = Inflector::underscore($this->controllerName);
		$check = str_replace('/', '_', $this->here);
		$replace = str_replace('/', '_', $this->base);
		$match = str_replace($this->base, '', $this->here);
		$match = str_replace('//', '/', $match);
		$match = str_replace('/' . $contoller . '/', '', $match);
		$match = str_replace('/' . $this->controllerName . '/', '', $match);
		$check = str_replace($replace, '', $check);
		$check = str_replace('_' . $contoller . '_', '', $check);
		$check = str_replace('_' . $this->controllerName . '_', '', $check);
		$check = Inflector::slug($check);
		$check = preg_replace('/^_+/', '', $check);
		$keys = str_replace('/', '_', array_keys($this->cacheAction));
		$found = array_keys($this->cacheAction);
		$index = null;
		$count = 0;

		foreach ($keys as $key => $value) {
			if (strpos($check, $value) === 0) {
				$index = $found[$count];
				break;
			}
			$count++;
		}
(後略)


Cacheは、1.3で「メソッドのコールの呼び出しの頻度と回数を減らすことに主眼が置かれました。」とあるので、
この違いも、仕様変更の一環なのかもしれません。


明確に記載されていないのと、マニュアル部分でも反映されていないようなので、注意が必要です。


CookBook for 1.3
http://book.cakephp.org/ja/view/1380/Caching-in-the-Controller
CookBook for 1.2
http://book.cakephp.org/ja/view/346/Caching-in-the-Controller