异常处理的最佳实践:PDO +控制器&资料库

时间:2013-11-05 19:18:47

标签: php exception orm exception-handling pdo

我一直在寻找有关在PDO中使用异常处理的最佳实践,但大多数示例仅从简单的一类方法中查看。

如果我在ORM类型模型中使用控制器和repo,那么各种try / catch和throw块应该在哪里发生?

简化示例:

CONTROLLER :(创建repo对象,触发loadProduct方法,并加载模板)

class ProductController {
public function viewProduct($product_id) {
    $ProductRepository = new ProductRepository($this->Pdo);
    $Product = $ProductRepository->loadProduct($product_id);

    include(__DIR__.'/../templates/product_template.php');
}
}

MODEL / REPOSITORY:

class ProductRepository
{
    private $Pdo;

    public function __construct(PDO $Pdo)
    {
        $this->Pdo = $Pdo;
    }

    public function loadProduct($product_id,$withimages=0)
    {

        $Stm = $this->Pdo->prepare('
            SELECT p.product_id,p.model,p.price,p.prodinfo,pi.image_path
            FROM products p LEFT JOIN product_images pi
            ON p.product_id = pi.product_id
            WHERE p.product_id = :product_id
            AND pi.is_primary = 1
        ');
        $Stm->bindParam(':product_id',$product_id,PDO::PARAM_INT);
        $Stm->execute();

        return $this->arrayToObject($Stm->fetch(PDO::FETCH_ASSOC));

    }

try / catch块是否应该放在控制器中,如果execute()没有返回任何内容则抛出异常?如果$ Pdo-> prepare()方法没有触发,会抛出一个单独的异常吗?

请帮忙!

1 个答案:

答案 0 :(得分:1)

通常,异常处理策略非常简单。特别是PDO。因为PDO仅在出现严重故障的情况下抛出一个,并且继续执行几乎没有意义 - 所以,只需默认停止即可。

因此,对于代码的平均部分,无论是模型,存储库还是其他,都不需要专门的处理。

只有在您遇到失败查询方案的某些地方,才能使用try-catch。最常用的场景是事务回滚。因此,如果您有事务,您可能希望将其包装在try中,然后在catch.中回滚

回答评论中的澄清:

这是两种截然不同的情景:

  • 如果SELECT无法找到产品,则没有例外。
  • 如果INSERT以某种方式创建了无效的SQL查询,那确实是一场灾难。

他们需要不同的处理方式。

对于第一种情况,您根本不需要任何例外,这是常规行为。只需在您的模板中有一个分支,上面写着“找不到任何东西”

对于第二个,创建一个自定义异常处理程序,记录错误,发送503,并显示通用503错误页面。