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,即使有路由错误。
- 不COS
赞赏任何帮助。
答
我已经工作了我自己。
我太傻了。在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));
}
//...
}
谢谢。你的回答可以帮助我很多! –
没问题。我很高兴你觉得它很有用。 –