Zend_Config を Zend_Cache してくれるプラグイン作った

Zend_Config ファイルはだいたい Zend_Cache させて使ってるんですが、Zend_Cache の記述をまとめて書けないだろうかと思いたちプラグイン化してみました。

http://framework.zend.com/manual/ja/zend.cache.html
http://framework.zend.com/manual/ja/zend.config.html

動作環境

OS: Ubuntu 9.0.4
PHP: 5.3.0
ZendFramework: 1.8.4

で確認しました。

解説

私は Zend_Config を使用する際、だいたい Zend_Cache の file を使ってファイルキャッシュさせて使っています。

.ini ファイルの更新日時を見て、更新されていなければキャッシュを見てくれるので、毎回 .ini ファイルをパースさせるよりオーバーヘッドがかかりません。

で、そうすると .ini ファイルを呼ぶ箇所全てに Zend_Cache の記述が必要になり、何も考えずに書いてると 例えば Controller の init() メソッドとか、model のコンストラクタに、使用する .iniファイル分の Zend_Cache の記述が並ぶ事になり、どうにかならんかなと考えてました。

<?php

    $cache = Zend_Cache::factory('File', 'File',
                array(
                        'lifetime' => NULL,
                        'automatic_serialization' => true,
                        'master_file' => '../application/configs/system.ini'
                ),
                array(
                        'cache_dir' => './cache/'
                )
        );
 
    if (!($config = $cache->load('system.ini'))) {
        $config = new Zend_Config_Ini('../application/configs/system.ini');
        $cache->save($config, 'system.ini');
    }

.ini ファイル一つにつき、上記のような記述が一回必要になります。

これをうまい事まとめれないかな、と。

解説2

その頃ちょうどリフレクションクラスを触ってたので、これを使って、docComment に使いたい configファイルを記述すると、勝手にキャッシュしてくれてれば便利だなと思いました。

/**
 * hogeAction
 *
 * @config system fuga piyo
 * @param string $hoge
 * @return bool
 */

みたいに docComment に書いとけば、system.ini, fuga.ini, piyo.ini を勝手にキャッシュしてくれてて、呼び出せる様にしてみます。

ディレクトリ構成など

githubリポジトリに、2つファイルをコミットしています。
Autocacher.php と autocacher.ini です。


デフォルトの設定では、ZendFramework は以下のような構成になっている事を想定しています。

application/
    configs/
    controllers/
    models/
    views/
public/

zfコマンド等でプロジェクト作成すると上記のような構成になっています。
又は、

application/
    configs/
    modules/
        controllers/
        models/
        views/
public/

のように、modulesを使用した構成。


configs/ の中に、autocacher.ini を設置。
ZFのライブラリの中に、Autocacher.php

Zend/
    Controller/
        Plugin/
            Autocacher.php

上記のような感じで設置します。


index.php などで、各Controllerへの include_path を通し、
Zend_Loader_Autoloader でオートロードの設定をしてください。


Zend_Cache のキャッシュファイル保存ディレクトリとして、public/ 直下に cache/ ディレクトリが無ければ プラグイン内部で mkdir で生成しようとします。
phpディレクトリを作成できる権限がなければ、あらかじめ cache/ ディレクトリを作ってください。

autocacher.ini の設定

autocacher.ini に、現在4つの設定項目があります。

cache_dir     = "../public/cache/"

config_dir    = "../application/configs/"

modules       = "on"

session_name  = "autocacher"

cache_dir は、cacheファイルを保存する cacheディレクトリのパスを指定できます。

config_dir は、各configファイルが設置されているディレクトリのパスを指定できます。
(autocacher.ini 自身は、/application/configs/ に設置してある事が前提です)

modules は、ディレクトリ構成に modules を使用しているかどうかを、'on' と 'off' で指定します。

session_name は、Zend_Configオブジェクトを保存する Zend_Sessionの名前空間を指定します。

controller の書き方

<?php

class IndexController extends Zend_Controller_Action
{
    public function init()
    {
        /* Initialize action controller here */
        $this->_c = new Zend_Session_Namespace('autocacher');
    }

    /**
     * indexAction
     *
     * @config system hoge
     */
    public function indexAction()
    {
        /** system.ini の fugaパラメータにアクセス */
        $this->_c->system->fuga;

        /** hoge.ini の piyo.hogehogeパラメータにアクセス */
        $this->_c->hoge->piyo->hogehoge;
    }
}

上記のように、init() 等の初期設定を行う箇所に、autocacher.ini で設定した名前空間のZend_Sessionを生成する記述を書きます。
プロパティに持たせ、クラス内の各アクションからアクセスできるようにしておきます。


各アクションの docComment に、

    @config[半角スペース]iniファイル名[半角スペース]iniファイル名

という感じに、使いたいiniファイル名を書きます。

これで、先ほど生成した Zend_Session オブジェクト内にZend_Configオブジェクトが生成されますので、簡単にアクセスする事ができます。

今後追加したい事

現在、controllerしか対応していないので、modelクラスにも対応させたい。
(今の仕様だと、model内で使うiniファイルは、あらかじめそのmodelを呼び出すcontrollerのdocCommentに書いておかないと使えない。)


Zend_Cache の File にしか対応していないが、他の保存方式も選べる様にしたい。


などでしょうか。
リフレクションクラスって、結構面白いプラグインが色々作れそうだと思うのですがどうでしょう。



あ、はてなパーカー欲しい!グレーのMが欲しい!



2009/11/26追記

Zend_Session より Zend_Registrey の方が気持ち悪く無い気がしてきたので仕様変更しようかな。

branch切った。Zend_Registryバージョンだと、autocacher.ini の session_name パラメータが不要。

    Zend_Registry::get('hoge')->fuga;

とかでアクセスできます。
セッションに持たせるよりこっちの方がスマートかも。こういう時にZend_Registryは役に立つのかな。