代码之家  ›  专栏  ›  技术社区  ›  joedevon

动作助手是否有自动运行的挂钩,是否抛出异常?

  •  1
  • joedevon  · 技术社区  · 14 年前

    更新

    希望每个控制器运行一些代码,并且 told @Bittarman (瑞安·莫格);

    http://www.slideshare.net/rmauger/zend-framework-getting-to-grips 见幻灯片22: 在(操作帮助程序)调度前/调度后引发异常

    虽然它确实停止了进一步的执行,但未捕获异常。我已经试着调试了好几个小时了,但还是没有成功。

    如果运行以下代码,您是否看到捕获到异常或它正在转义错误控制器?

    我试图弄清楚Zend框架是否没有按预期的方式运行,或者是否完全弄糟了某些事情(更可能)。

    我试着把这个分解成最简单的例子来复制,让我知道你看到了什么:

    /*添加到这里的现有引导程序:Apple PosithPosie/BootStruP.PHP*/

    protected function _initActionHelpers()
    {
        Zend_Controller_Action_HelperBroker::addPath(APPLICATION_PATH .'/controllers/helpers');
        //hooks cause action helper to autorun: http://akrabat.com/zend-framework/hooks-in-action-helpers/
        $hooks = Zend_Controller_Action_HelperBroker::getStaticHelper('Test');
        Zend_Controller_Action_HelperBroker::addHelper($hooks);
    }
    

    <?php
    class Zend_Controller_Action_Helper_Test extends Zend_Controller_Action_Helper_Abstract
    {
    
        public function preDispatch()
        {
            // you can skip next line if you don't have xdebug
            //xdebug_disable();
            throw new Exception('test', 404);
            parent::preDispatch();
        }
    }
    

    更新: 好的,我已经通过xDebug+Eclipse运行了这个。。。(要么是这样,要么是开心地把眼睛伸出来,不确定我是否选择了更愉快的体验)……我发现了一些奇怪的事情。

    预兆已经持续了两次! 在第二个调用中,它转到Zend_Controller_Plugin/ErrorHandler.php

    if ($this->_isInsideErrorHandlerLoop) {
        $exceptions = $response->getException();
        if (count($exceptions) > $this->_exceptionCountAtFirstEncounter) {
            // Exception thrown by error handler; tell the front controller to throw it
            $frontController->throwExceptions(true);
            throw array_pop($exceptions);
        }
    }
    

    通过将throw Exceptions设置为true,它将不再被捕获。我怀疑这是为了避免循环的发生(>\u isInsideErrorHandlerLoop也是一个微妙的线索;)

    为什么是一个循环?

    2 回复  |  直到 7 年前
        1
  •  5
  •   joedevon    14 年前

    “好吧,”比塔曼在IRC的ZFTalk中给了我答案。这是(很抱歉,我会把自己的答案标为正确的……但我不想再打扰他把它写在这里了)。

    if( ($this->getRequest()->getActionName() == 'error') && ($this->getRequest()->getControllerName() == 'error')) {
        return;
    }
    

    原因是错误处理程序必须禁用自身 处理程序循环。所以你有 以确保错误控制器中不会出现异常情况。

        2
  •  3
  •   Fge    14 年前

    在这之前它不会捕获异常,就像在preDispatch中一样。

    在您的情况下,该异常不会被frontcontroller捕获,因此会被抛出到应用程序的最顶端。您确实可以编辑frontController以在分派之前捕获异常-但这不是故意实现的:分派之前的所有操作都可以看作是“启动”应用程序:任何异常都是关键的。与实际引导一样,任何异常都会停止应用程序的运行。所以你真的应该避免任何例外。

    更新
    但是错误处理程序是做什么的?它会用您的errorController向FrontController添加另一个请求。因此,另一个分派循环完成了,然后,actionhelper确实抛出了一个异常。由于errorController请求与任何其他请求没有区别,ErrorHandler插件将再次捕获它并链接errorController的另一个请求。又一次。。我想你可以看到这会导致什么-一个循环。为了防止这种情况,有一个属性来查看是否已经在某个地方出现了异常。这将捕获错误处理程序引发的任何异常。如果ErrorHandler插件注意到这样的异常,它会将throwException属性覆盖为true并抛出异常。

    我可以看出ActionHelpers可以抛出异常,但出于这个原因,您应该非常小心;)