
先日、モデルにキャッシングを実装するタスクがありました。 同僚との議論の中で、私の意見では、かなり興味深いアイデアが生まれました。あなたの裁判所に提出したいと思います。
Zend Frameworkでアイデアを実装する :
1.すべてのモデルは、
My_Db_Table_Abstractクラスを継承します。
class My_Model_ModuleSettings extends My_Db_Table_Abstract
2.
Zend_Db_Table_Abstractを継承するもの :
class My_Db_Table_Abstract extends Zend_Db_Table_Abstract
3.すべてのモデルの基本
であるクラス
My_Db_Table_Abstractで 、魔法の
__call()メソッド
を説明します。
public function __call($name, $arguments)
{
/** If call cached method */
if (preg_match( '/^cached_(.+)$/' , $name, $methodName)&&method_exists($ this ,$methodName[1])) {
/** Get cache instance */
$cache = My_Cache::getInstance();
/** Get arguments hash */
$argHash = md5(print_r($arguments, true ));
/** Get model class name */
$className = get_class($ this );
/** If method result don't cached */
if (!$result = $cache->load( 'model_' .$className. '_' .$methodName[1]. '_' .$argHash)) {
$result = call_user_method_array($methodName[1], $ this , $arguments);
$cache->save($result,
'model_' .$className. '_' .$methodName[1]. '_' .$argHash,
array( 'model' ,$className,$methodName[1]));
}
return $result;
} else {
/** Generate exception */
throw new Exception( 'Call to undefined method ' .$name);
}
}
これで、
モデルメソッドを2つの方法で使用できるようになりました 。
1.キャッシュなしで、メソッドを参照するだけです:
$result = $ this ->_life->getAll( 'Now!!' );
2.キャッシュし、プレフィックス「cached_」をメソッド名に追加します。
$result = $ this ->_life->cached_getAll( 'Now!!' );
存在しないメソッドを参照する2番目のケースでは、
__ call()メソッドがトリガーされ、キャッシュされた結果の存在がチェックされます。 メソッドの実行結果がキャッシュされる場合、キャッシュが使用されます。キャッシュされない場合、メソッドが呼び出され、結果がキャッシュされます。
いくつかのニュアンス :
1.メソッドの実行結果のキャッシュがメソッドのパラメーターによって異なるようにするために、パラメーターのハッシュを作成しました。
$argHash = md5(print_r($arguments));
これはおそらく最も物議を醸す瞬間です。なぜなら、 これがパフォーマンスにどのように影響するかを正確に言うことはできません(テスト中、負荷の増加は認められませんでした)。 さまざまなハッシュ関数(md5()、sha1()..)および変数の配列を文字列型にキャストするさまざまな方法(print_r()、var_dump()、implode())を使用できます。
2.キャッシュされたファイルの名前は、
model_ClassName_HashParameters_Nameという形式に
なりますが、一致する可能性はあり
ません 。
3.キャッシュにはタグ
'model' 、
'className'および
'methodName'がタグ付けされており、クリーニングの操作が簡単になります。
My_Model_ModuleSettingsモデルのすべてのメソッドのキャッシュをクリアする例を次に示します。
$cache->clean(
Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG,
array( 'My_Model_ModuleSettings' )
);
私はあなたのコメントを聞きたいです...この方法の欠点は何ですか? 彼には命の権利がありますか?