我有几个模块,一个是API。我想为此API模块设置不同的ErrorHandler。
因为当触发默认的ErrorHandler时,它使用默认模块,默认模式包含HTML。我不希望我的API返回。
我已经在这里和Zend Docs上看过了,并且没有提出任何允许我这样做的事情。
感谢您的帮助。
答案 0 :(得分:4)
这是我使用的那个:
<?php
class My_Controller_Plugin_Modular_ErrorController extends Zend_Controller_Plugin_Abstract
{
public function routeShutdown (Zend_Controller_Request_Abstract $request)
{
$front = Zend_Controller_Front::getInstance();
// Front controller has error handler plugin
// if the request is an error request.
// If the error handler plugin is not registered,
// we will be unable which MCA to run, so do not continue.
$errorHandlerClass = 'Zend_Controller_Plugin_ErrorHandler';
if (!$front->hasPlugin($errorHandlerClass)) {
return false;
}
// Determine new error controller module_ErrorController_ErrorAction
$plugin = $front->getPlugin($errorHandlerClass);
$errorController = $plugin->getErrorHandlerController();
$errorAaction = $plugin->getErrorHandlerAction();
$module = $request->getModuleName();
// Create test request module_ErrorController_ErrorAction...
$testRequest = new Zend_Controller_Request_Http();
$testRequest->setModuleName($module)
->setControllerName($errorController)
->setActionName($errorAaction);
// Set new error controller if available
if ($front->getDispatcher()->isDispatchable($testRequest)) {
$plugin->setErrorHandlerModule($module);
} else {
return false;
}
return true;
}
}
(顺便说一句,这个问题已经在这里讨论过了,仔细看。)
答案 1 :(得分:1)
@takeshin:感谢您分享您的插件,这太棒了!而这正是我在谷歌机器上寻找的东西。
我尊重地对确定请求为“错误请求”的逻辑做了一些更改,因为我发现每个请求都运行完整的插件回调,无论是否发生错误。< / p>
我刚刚将插件挂钩更改为“postDispatch”并测试了在调度期间实际发生了异常。其余代码的功能与您的完全相同。
现在,您可以在插件中间放置一个die语句,只有在请求期间发生异常后才能看到它。
<?php
class Rm_Controller_Plugin_Modular_ErrorController
extends Zend_Controller_Plugin_Abstract
{
public function postDispatch(Zend_Controller_Request_Abstract $request)
{
$front = Zend_Controller_Front::getInstance();
// true if response has any exception
$isError = $front->getResponse()->hasExceptionOfType('Exception');
// if there was no error during dispatch
if (!$isError) {
return false;
}
// standard error handler plugin class name
$errorHandlerClass = 'Zend_Controller_Plugin_ErrorHandler';
// if the error handler plugin is not registered, do not continue.
if (!$front->hasPlugin($errorHandlerClass)) {
return false;
}
$plugin = $front->getPlugin($errorHandlerClass);
// the module that was requested and threw error
$module = $request->getModuleName();
// the controller & action name that error handler will dispatch
$errorController = $plugin->getErrorHandlerController();
$errorAction = $plugin->getErrorHandlerAction();
// create a dummy request to test for dispatchablility
$testRequest = new Zend_Controller_Request_Http();
$testRequest->setModuleName($module)
->setControllerName($errorController)
->setActionName($errorAction);
// verify that the current module has defined an ErrorController::errorAction
if ($front->getDispatcher()->isDispatchable($testRequest)) {
// tell error controller plugin to use the module's error controller
$plugin->setErrorHandlerModule($module);
} else {
return false;
}
return true;
}
}
答案 2 :(得分:0)
在我的脑海中,您可以从控制器插件中将原始请求对象的副本存储在注册表中。在控制器的preDispatch()中,您可以根据请求的模块转发到另一个错误控制器。
// Plugin
public function routeStartup(Zend_Controller_Request_Abstract $request)
{
$clonedRequest = clone $request;
Zend_Registry::set('originalRequest', $clonedRequest);
}
// ErrorController
public function preDispatch()
{
$request = Zend_Registry::get('originalRequest');
$this->_forward('error', 'error', $request->getModuleName());
}