Zend框架1 - 如何从一个插件内的routeShutdown

问题描述:

检测路由错误的Zend Framework 1.11.11Zend框架1 - 如何从一个插件内的routeShutdown

我写一个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

    • 名称不COS的工作没有被设置为错误动作又
  • 检查异常响应对象

    • 不COS $this->getResponse()->isException()工作似乎返回˚F ALSE,即使有路由错误。

赞赏任何帮助。

我已经工作了我自己。

我太傻了。在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()方法测试
  • 一般例外,或
  • undispatchable控制器
  • 操作方法是做不存在。 (我避免在我的项目中使用魔法,所以我知道如果方法没有声明,那么它不会奏效。)

所以:

<?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)); 
     } 

    //... 

    } 
+1

谢谢。你的回答可以帮助我很多! –

+1

没问题。我很高兴你觉得它很有用。 –