[ ZendFramework1 ] プラグインの登録と解除(リクエストを制御してアクションを振り分ける)

Pocket

ここでは、Zend Framework1 におけるプラグインの登録と解除を行うサンプルコードを掲載しています。サンプルとしてリクエストを強制的に別アクション(URL)へ振り分けを行っています。

スポンサーリンク

プラグインの作成と登録

プラグインを Bootstrap で登録し、呼び出されたアクションを強制的に切り替えるサンプルコードになります。Bootstrap でプラグインを登録することで全てのアクションリクエストの実行前にプラグインが実行されるようになります。詳細はサンプル内のコメントを参照ください。

作成・登録するサンプルプラグイン

class Sample_Plugin extends Zend_Controller_Plugin_Abstract
{
    private $_flag = 'off'; // アクションスキップ(切り替え)フラグ

    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        // 何らかの条件でフラグを on にする
        if( ... ) {
           $this->_flag = 'on';
        }

        // フラグが on の場合
        if($this->_flag == 'on') {
        
            // 現在のリクエストをキャンセルし error/error アクションを実行させる
            $request->setModuleName('default')
                    ->setControllerName('error')
                    ->setActionName('error')
                    ->setDispatched(false);

            // フラグを off にしないと、無限ループする
            $this->_flag  = 'off';
        }
    }
}

Bootstrap でサンプルプラグインを登録

require_once 'plugins/Sample_Plugin.php';

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    /**
     * プラグインの登録
     */
    protected function _initRegisterPlugins()
    {
        // プラグインのインスタンス生成
        $pin = new Sample_Plugin();

        // フロントコントローラオブジェクトを取得
        $this->bootstrap('frontController');
        $frontController = $this->getResource('frontController');

        // プラグインをフロントコントローラに登録(小さい数ほど優先度が高い)
        $frontController->registerPlugin($pin,  10);
    }
}

デフォルトで flag は off ですが、何かしらの条件によって flag を on にし、要求されたリクエストを error コントローラの error アクション振り分けています。アクション(URL)を切り替えた後で、フラグを off に設定している点がポイントです。このフラグの解除処理がない場合、error アクション前にも再度このプラグインが呼び出されるので、無限ループとなってしまいます。

これらのことより、「リクエストアクションをキャンセルして、次アクションを設定した Sample_Plugin オブジェクトと次アクション前に呼び出される Sample_Plugin オブジェクトは同一であり、メンバ変数が初期化されることもない」 ことが言えます。同一オブジェクトであることを利用して制御することもできることを意味しています。

プラグインの解除

上記のサンプルでは、プラグインを登録したまま制御を行っていますが、一度きりの制御で良ければプラグインを解除してしまうことでも同様の制御を行うことができます。次のサンプルコードで確認できます。

プラグインの登録を解除する

class Sample_Plugin extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        // 何かエラーがあればアクションをスキップし別アクションを起動する
        if( ... ) {
            $request->setModuleName('default')
                    ->setControllerName('error')
                    ->setActionName('error')
                    ->setDispatched(false);

            /*
             * プラグインの登録を解除しているので次アクション実行時には
             * 本メソッドはコールされない
             */
            // フロントコントローラオブジェクトを取得し、プラグインの登録解除
            $front = Zend_Controller_Front::getInstance();
            $front->unregisterPlugin($this);
        } 
    }
}
参考
スポンサーリンク

Pocket

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>