【问题标题】:Handling Exceptions thrown in Zend Framework's Controller Plugins处理 Zend Framework 的控制器插件中抛出的异常
【发布时间】:2011-04-02 16:10:46
【问题描述】:

我有一个扩展 Zend_Controller_Plugin_Abstract 的 Acl 插件,这个插件处理我所有的 Acl 代码。

我想在这个插件中抛出一个异常,例如一个Exception_Unauthorised,然后在我的ErrorController 中处理这个问题,这样我可以为不同的应用程序使用相同的Acl 插件,并使用ErrorController 以不同的方式处理每个应用程序中的每种情况——如果需要的话。

问题是在插件中抛出异常并不会阻止原始Action执行。所以我最终得到了原始 Action 的输出和ErrorController 输出。

如何在插件中抛出异常以阻止原始操作发生?

案例 1

// This throws the `Exception_NoPermissions`, but it does not get caught by
// `ErrorController`
public function preDispatch(Zend_Controller_Request_Abstract $request)
{       
    parent::preDispatch($request);
    throw new Exception_NoPermissions("incorrect permissions");
}

案例 2

// This behaves as expected and allows me to catch my Exception
public function preDispatch(Zend_Controller_Request_Abstract $request)
{       
    parent::preDispatch($request);
    try
    {
        throw new Exception_NoPermissions("incorrect permissions");
    }
    catch(Exception_NoPermissions $e)
    {

    }
}

案例 3

我认为这就是问题所在,通过更改控制器。

public function preDispatch(Zend_Controller_Request_Abstract $request)
{       
    parent::preDispatch($request);

    // Attempt to log in the user

    // Check user against ACL

    if(!$loggedIn || !$access)
    {
        // set controller to login, doing this displays the ErrorController output and
        // the login controller
        $request->getControllerName("login");
    }
}

【问题讨论】:

    标签: php zend-framework plugins exception-handling


    【解决方案1】:

    这就是我的工作。

    // Get Request Object...
    $request = $this->getRequest();
    // Do manual redirect.. select your own action...
    $this->getRequest()->setControllerName('error')->setActionName('could-not-find-destination')->setDispatched(true);
    $error = new Zend_Controller_Plugin_ErrorHandler();
    $error->type = Zend_Controller_Plugin_ErrorHandler::EXCEPTION_OTHER;
    $error->request = clone( $request );
    $error->exception = $e; // If you have caught the exception to $e, set it. 
    $request->setParam('error_handler', $error);
    

    【讨论】:

      【解决方案2】:
      【解决方案3】:

      我在#zftalk IRC 频道上对此进行了简短的交谈,Ryan Mauger / Bittarman 表示,如果插件中发生异常,目前您需要手动重定向用户。

      我也有一个想法,也许你可以使用一个单独的插件来检查异常。如果您查看 ErrorHandler 插件,它会检查请求是否包含异常并对其进行操作。

      问题是 ErrorHandler 在 routeShutdown 时触发,例如。当请求已经完成时。如果您创建了一个查看异常但在 preDispatch 上运行的自定义插件,则可以自动执行此任务。

      请注意,您需要确保在任何可能引发异常的插件之后运行此自定义插件。

      【讨论】:

      • 这一切都说得通。我想我宁愿重定向用户并以这种方式处理它。而不是创建一个插件来捕获其他插件中的异常 - 最终可能会让我更加困惑!
      • 我将此标记为答案,因为您似乎无法做我想做的事,但这是最接近那里的地方。
      【解决方案4】:

      这应该可行。这一切都取决于您何时何地抛出异常。看看这篇博文:

      Handling errors in Zend Framework | CodeUtopia - The blog of Jani Hartikainen

      【讨论】:

      • 看看那篇文章的最后一条评论 - codeutopia.net/blog/2009/03/02/… - 来自我。 :-) 我在我的Zend_Controller_Plugin_Abstract 中抛出了preDispatch() 中的错误@
      • @jakenoble,粘贴一些代码。你什么时候打电话给parent::preDispatch()error_handler 已经注册了吗?
      • @takeshin 我认为 error_handler 没有注册。如果我在preDispatch() 中的try { } 语句之外抛出异常,它不会被ErrorController 捕获。我没有明确设置应用程序不注册error_handler。我是否需要在我的 Bootstrap 类中显式加载它以确保它存在于我的插件中?
      • 我想你可能只是让互联网泄漏了内存。 ;)
      • @jakenoble,您为什么不直接粘贴不起作用的完整代码?设置error_reporting(-1) 看看发生了什么。
      猜你喜欢
      • 2018-10-31
      • 1970-01-01
      • 2011-04-21
      • 1970-01-01
      • 2012-07-07
      • 2011-02-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多