私はそれを自分で解決しました。
私は愚かだった。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 ) );
}
//...
}