2

Zend 框架 1.11.11

我正在编写一个 Zend 框架控制器插件,它在routeShutdown钩子中做一些事情。

如果出现路由错误,我希望能够避免运行我的进程。

即,如果我们只是得到一个 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()似乎返回 FALSE,即使出现路由错误也是如此。

任何帮助表示赞赏。

4

1 回答 1

3

我自己已经解决了。

我是愚蠢的。在 routeShutdown 我们不知道它是否会是一个 404 页面类型错误,直到我们尝试调度它。

所以我们能做的就是

  • 测试响应中的一般异常
  • 询问调度员该路线是否可能是可调度的。

所以插件无法真正确定是否存在“路由错误” - 所以它必须询问“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 回答