在 Zend Framework 应用程序中从模型/视图/控制器中抛出异常

Posted

技术标签:

【中文标题】在 Zend Framework 应用程序中从模型/视图/控制器中抛出异常【英文标题】:Throwing exceptions from model/view/controller in a Zend Framework application 【发布时间】:2011-04-21 01:49:57 【问题描述】:

在 Zend Framework 库中,当前的做法(大约 1.10.8)是库组件抛出扩展 Zend_Exception 的异常。

例如Zend_Layout 组件抛出 Zend_Layout_Exception

在我自己的 ZF 库中,我正在添加自己的 ZF 组件或扩展现有组件,我抛出了一个 Mylibrary_Exception(当然,它并没有真正被称为 :)

我可以看到他们将在 ZF 2.0 中更改其中的一些内容

http://framework.zend.com/wiki/display/ZFDEV2/Proposal+for+Exceptions+in+ZF2

我的实际问题是:

在我的控制器/模型/视图中的整个 MVC 应用程序中,如果我需要抛出异常(这种情况很少见,因为显然我将以不同的方式处理预期的错误) - 但如果我确实需要在这里抛出异常,ZF的最佳实践是什么?

我应该只是

throw new Exception("this is an exception");

或者我应该在我的 ZF 模块中创建异常类,类似于 ZF 库的组织方式。即它们为每个库组件都有异常类,我应该为每个应用程序模块设置异常类吗?

应用程序/模块/用户/控制器/UserController.php

应用程序/模块/用户/表单/UserForm.php

应用程序/模块/用户/模型/User.php

应用程序/模块/用户/视图/脚本/index.phtml

application/modules/user/exceptions/Exception.php(User_Exception 类)

application/modules/user/exceptions/SuperexampleException.php(类 User_Exception_Superexample)

我以前从未在 ZF 看到有人做过这样的事情,所以我不确定这是否是个好主意。

更新

为了进一步澄清我的问题 - 在应用程序的 MVC 部分(而不是库)中引发异常时 - 是否有关于使用特定异常类(如库)与仅使用通用异常类的约定?

【问题讨论】:

【参考方案1】:

我建议有一些“通用”异常,例如 (InvalidParameter, InvalidRange) 好的起点是czech framework called Nette。

然后添加一些应用程序/用户/操作特定的异常 - 比如

InvalidUserInputException - 对于用户输入无效值的状态(例如“-1”作为 eshop 中的数量) NotFoundException - 用于未找到某些东西的状态 等

将特殊的成员变量添加到这些异常中 - 例如 iddata - 并使用它们来使用异常作为错误消息的传递。

$e = new NotFoundException('There is no user %s in here!');
$e->setUser('Frank');
throw $e;
// later in error controller
if ($e instanceof NotFoundException) 
    // set header to 404, display error message, etc

好消息是您可以随心所欲地扩展异常,并随心所欲地在错误控制器中捕获它们(更好的是使用接口)

class AccessDeniedExceptionimplements ILogableException
//...
throw new AccessDeniedException();
//in EC
if ($e instanceof ILoggableException) 
    $this->getLogger()->log($e->getLogMessage());

【讨论】:

【参考方案2】:

ZF V1 中的抛出异常由默认的错误控制器处理

  $errors = $this->_getParam('error_handler');

        switch ($errors->type) 
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ROUTE:
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:

                // 404 error -- controller or action not found
                $this->getResponse()->setHttpResponseCode(404);
                $this->view->message = 'Page not found';
                break;
            default:
                // application error
                $this->getResponse()->setHttpResponseCode(500);
                $this->view->message = 'Application error';
                break;
        

如果你需要捕获自定义异常,你需要将它们添加到错误控制器中 这是一种简单方便的方法,我喜欢它,我很满意

【讨论】:

错误控制器用于处理异常——而不是抛出它们。如果我在 MVC 应用程序中引发异常(如我在问题中所述),那么我的错误控制器将处理/捕获该错误,因为它会一直冒泡到前端控制器,然后转发到我的错误控制器。您不会从错误控制器引发应用程序异常 - 您会在应用程序中需要发生它们的地方引发它们! 我在第一个条款中已经说过,那是 ZF v1 最佳实践,我将加粗该条款以使其更清楚

以上是关于在 Zend Framework 应用程序中从模型/视图/控制器中抛出异常的主要内容,如果未能解决你的问题,请参考以下文章

Zend Framework,FusionCharts,PHP,Javascript

Zend Framework 和 Doctrine 2 - 我的单元测试是不是足够?

我可以在 Play Framework 2.4 中从两个没有转换器的模型中编写 Json

Zend Framework ORM 样式表数据网关与扩展 Zend_Db_Table_Abstract

Zend Framework 中的动态菜单

Zend Framework 2 中的数据库访问