在MVC架构中记录数据库错误的位置

时间:2013-01-11 10:18:08

标签: php model-view-controller logging error-handling zend-framework2

或任何相关的框架。

以Zend Framework 2为例,我有以下表类:

<?php

namespace Contact\Model;

use Zend\Db\TableGateway\TableGateway;
use Zend\Db\TableGateway\AbstractTableGateway;
use Zend\Log\Logger;

class UserContactsTable extends AbstractTableGateway
{
    protected $tableGateway;

    /**
     *
     * @var \Zend\Log\Logger Instance
     */
    protected $logger;

    public function __construct(TableGateway $tableGateway, Logger $logger )
    {
        $this->tableGateway = $tableGateway;
        $this->logger       = $logger;
    }

    /**
     * Save a contact
     * 
     * @param \Sms\Model\UserContact $userContact
     */
    public function saveUserContact(UserContact $userContact)
    {
        $data = array(
            'user_id'       => $userContact->user_id,
            'contact_id'    => $userContact->contact_id
        );

        try {
            $this->tableGateway->insert($data);
        } catch (\Exception $e) {
                    //log
            $this->logger->crit($omeErrMsg);

        }
    }
}
?>

我应该在这里登录吗?我应该将记录器绑在表类中吗? 如果插入失败并在控制器中捕获并记录在那里,我是否应该让saveUserContact函数抛出异常?

最佳做法是什么?

我最初的想法是创建一个带有一些常量错误消息的类,例如记录器在表类中使用的插入和更新失败,但我不确定这里的正确过程是什么。

这并不仅限于PHP或Zend Framework 2,但恰好是我正在使用的语言。

2 个答案:

答案 0 :(得分:6)

我认为系统的各个组件应该尽可能地分离。所以在这个例子中,如果saveUserContact碰巧失败,那么它应该可能导致抛出异常,因为这不是预期的行为。这个类不需要知道“进一步向上”会发生什么,例如错误记录。

正如您所提到的,最好抛出异常并将其捕获到您的控制器(或者其他形式的侦听器)中,然后处理日志记录。

这种方法的好处是您的系统将更容易测试,因为在构造要测试的UserContactsTable(模拟)对象时,您将拥有更少的存根对象。

答案 1 :(得分:2)

一般来说,我觉得你应该记录失败的地方(除非它们是预期的,在这种情况下是嘈杂的)但是在堆栈上传播异常(或者包装器异常)所以调用者可以决定是否忽略/重试/失败(并记录自己的,更多与业务逻辑相关的消息)。