2

Zend フレームワーク 1.11.11

routeShutdownフックで処理を行う Zend Framework コントローラー プラグインを作成しています。

ルーティング エラーが発生した場合に、プロセスの実行を回避できるようにしたいと考えています。

つまり、404 エラーが発生するだけなら、プロセスを実行したくありません。

class MyPlugin extends Zend_Controller_Plugin_Abstract
    {


    public function routeShutdown( Zend_Controller_Request_Abstract $zfRequestObj )
        {

        if ( $this->isRoutingError() )
            {
            //there was a routing error do not do any intensive page start up stuff
            return;
            }

        return $this->doRouteShutdownProcesses( $zfRequestObj );                
        }

    protected function isRoutingError()
            {
            //?? So how do we get this?
            }
    ...

    }

では、この時点でルーティング エラーがあったかどうかを判断するにはどうすればよいでしょうか。

私が試したこと。

  • requestObj のモジュール、コントローラー、アクション名を確認してください

    • エラー アクションがまだ設定されていない場合は動作しません
  • 応答オブジェクトの例外を確認します

    • $this->getResponse()->isException()ルーティング エラーが発生した場合でも、cosは FALSE を返すように見えます。

どんな助けでも感謝します。

4

1 に答える 1

3

私はそれを自分で解決しました。

私は愚かだった。routeShutdown では、404 ページ タイプのエラーになるかどうかは、ディスパッチしてみるまでわかりません。

だから私たちにできることは

  • 応答の一般的な例外をテストします
  • ルートが Dispatchable である可能性が高いかどうかをディスパッチャーに尋ねます。

そのため、プラグインは「ルーティング エラー」があるかどうかを実際に判断できません。したがって、「isRouteShutdownToBeSkipped()」に問い合わせる必要があります。

<?php

class MyPlugin extends Zend_Controller_Plugin_Abstract
    {


    public function routeShutdown( Zend_Controller_Request_Abstract $zfRequestObj )
        {

        if ( $this->isRouteShutdownToBeSkipped( $zfRequestObj ) )
            {
            //do not do any intensive page start up stuff
            return;
            }

        return $this->doRouteShutdownProcesses( $zfRequestObj );                
        }

    //...

次に、 isRouteShutdownToBeSkipped() メソッドがテストします

  • 一般的な例外、または
  • ディスパッチできないコントローラー
  • 存在しないアクション メソッド。(私は自分のプロジェクトで魔法を使うことを避けているので、メソッドが宣言されていなければ、うまくいかないことはわかっています。)

そう:

<?php

class MyPlugin extends Zend_Controller_Plugin_Abstract
    {

    //...

    protected function isRouteShutdownToBeSkipped( Zend_Controller_Request_Abstract $zfRequestObj )
        {   

        if ( $this->getResponse()->isException() )
            {
            //Skip cos there was an exception already.
            return TRUE;
            }

        if (!( $this->isDispatchable( $zfRequestObj ) )) 
            {
            //Skip cos route is not dispatchable (i.e no valid controller found).
            return TRUE;
            }


        if (!( $this->actionMethodExists( $zfRequestObj ) ))
            {
            //There is no action method on the controller class that 
            //resembles the requested action.
            return TRUE;
            }

        //else else give it a go
        return FALSE;
        }
    //...

私のisDispatchable()メソッドは単にディスパッチャに委譲します:

<?php

class MyPlugin extends Zend_Controller_Plugin_Abstract
    {

    //...

    protected function isDispatchable( Zend_Controller_Request_Abstract $zfRequestObj )
        {
        return Zend_Controller_Front::getInstance()
            ->getDispatcher()
            ->isDispatchable( $zfRequestObj );      
        }
    ...

私のactionMethodExists()方法はもう少し複雑です。ディスパッチャーのインターフェースは少し誤解を招く (getControllerClass()実際にはクラス名を返さない) ため、実際のコントローラー クラス名を取得するためにいくつかの手順を踏まなければならず、PHP の組み込みmethod_exists()関数の呼び出しに間に合うようにクラスをロードする必要があります。

<?php    
class MyPlugin extends Zend_Controller_Plugin_Abstract
    {    
    //...

    /**
    * @desc 
    * @returns boolean - TRUE if action method exists
    */
    protected function actionMethodExists( Zend_Controller_Request_Abstract $zfRequestObj )
        {

        //getControllerClass() does not return the module prefix
        $controllerClassSuffix = Zend_Controller_Front::getInstance()
            ->getDispatcher()
            ->getControllerClass( $zfRequestObj );


        $controllerClassName = Zend_Controller_Front::getInstance()
            ->getDispatcher()
            ->formatClassName( $zfRequestObj->getModuleName() , $controllerClassSuffix );


        //load the class before we call method_exists()
        Zend_Controller_Front::getInstance()
            ->getDispatcher()
            ->loadClass( $controllerClassSuffix );

        $actionMethod = Zend_Controller_Front::getInstance()
            ->getDispatcher()
            ->getActionMethod( $zfRequestObj );

        return ( method_exists( $controllerClassName, $actionMethod ) );
        }

    //...

    }
于 2012-05-03T18:56:20.787 に答える