CakePHP Behaviorでモデルのメソッドキャッシュ with find() オーバーライド

元ネタは以下2つのエントリー。

http://www.exgear.jp/blog/2008/11/cakephp12-behavior%E3%81%A7%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AE%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5%E3%82%92%E8%A1%8C%E3%81%86/

http://blog.katsuma.tv/2009/04/cakephp_model_cache.html


車輪の再発明というわけではないですが、好みに併せて少し改変。
メモ代わりに残します。

目的

サイト全体の高速化
View cache を利用出来ない部分が主

メリット/デメリット

http://blog.katsuma.tv/2009/04/cakephp_model_cache.html
上記ページに分かり易く記載されているので、ここでは簡潔に。

最大のメリットは
キャッシュを意識することなく、クエリーキャッシュを利用することが出来る事。

逆にデメリットは
完全な最適化が行われるわけではないので、最も早くなるわけではない。
ま、これは個別に対応すればよいという整理。

導入手法

1)CacheBehavior を導入
ソースは以下から。
http://www.exgear.jp/blog/2008/11/cakephp12-behavior%E3%81%A7%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AE%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5%E3%82%92%E8%A1%8C%E3%81%86/

動作させるために、Model に Behavior 属性を記載。
怠慢な私は、app_model.php に記載しちゃってます。


2)find() をオーバーライド
app_model.php 上で find() をオーバーライド。
以下のような形で、キャッシュでフォルト設定から Duration(キャッシュ有効時間)を引き継いでます。
また、明示的に Duration を指定したい場合に備えて、 $options 内に属性を勝手に定義。まめにキャッシュをクリアしたいコンテンツなどで利用してます。

<?php
/**
 * Find over write.
 * モデルキャッシュを利用するために
 * 
 * @link http://blog.katsuma.tv/2009/04/cakephp_model_cache.html
 */
function find($type, $queryData = array())
{
     switch ($type) {
     case '任意のタイプ':
          return $this->find('all', Set::merge(array("conditions"=>array('任意の検索条件')), $queryData));

     default:
     // Set cache duration
          if (is_array($queryData) && isset($queryData['cacheDuration']) && !empty($queryData['cacheDuration'])) {
               $cacheDuration = $queryData['cacheDuration'];
               unset($queryData['cacheDuration']);
          } else {
               $cacheSetting = Cache::settings();
               $cacheDuration = $cacheSetting['duration'];
          }
          if (!is_numeric($cacheDuration)) {
               $cacheDuration = strtotime($cacheDuration) - time();
          }
          if ($cacheDuration < 1) {
               return false;
          }
     // Call cache method
          $args = array($type, $queryData);
          if ($this->Behaviors->attached('Cache')) {
               if($this->cacheEnabled()) {
                    return $this->cacheMethod($cacheDuration, __FUNCTION__, $args);
               }
          }
     // Case normal find. The model does not have cache behavior.
          return parent::find($type, $queryData);
     }
}
?>

3)Model->field() で Warning が。

検索条件を指定する部分は

<?php
$hoge_id = $this->field('hoge_id', array('id' => $id));
?>

では駄目でした。

<?php
$hoge_id = $this->field('hoge_id', array('Fuga.id' => $id));
?>

という形で、Model 名を明示的に指定すればOK
親クラスのメソッドを使ってるからだろと。

なぜ動かない?

実装の途中で不可解な事象に遭遇。何故だろう?

最終的に

<?php
return parent::find($type, $queryData);
?>

とした部分。

情報ソースのサイトでは

<?php
$parent = get_parent_class($this);
return call_user_func_array(array($parent, __FUNCTION__), $args);
?>

となっていた。
ソースを眺めた時点では、特に気にする事はなかったのだが。。。
いざ実行してみると、真っ白画面が。。。

インスタンス参照の問題?