根据模块设置不同的错误处理程序 - Zend Framework

时间:2010-06-10 09:51:43

标签: zend-framework

我有几个模块,一个是API。我想为此API模块设置不同的ErrorHandler。

因为当触发默认的ErrorHandler时,它使用默认模块,默认模式包含HTML。我不希望我的API返回。

我已经在这里和Zend Docs上看过了,并且没有提出任何允许我这样做的事情。

感谢您的帮助。

3 个答案:

答案 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());
}