处理Zend Framework的Controller插件中抛出的异常

时间:2010-08-23 14:03:32

标签: php zend-framework plugins exception-handling

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

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

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

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

案例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");
    }
}

4 个答案:

答案 0 :(得分:5)

答案 1 :(得分:4)

我在#zftalk IRC频道上快速聊了一下,Ryan Mauger / Bittarman说,如果插件中发生异常,你需要手动重定向用户。

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

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

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

答案 2 :(得分:0)

这应该有效。这一切都取决于您何时或何地抛出异常。看一下这篇博文:

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

答案 3 :(得分:0)

这就是我的工作。

// 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);