简体   繁体   English

异常处理的最佳实践:PDO + 控制器和存储库

[英]Best practice for exception handling: PDO + controllers & repositories

I've searched around for best practices on using exception handling with PDO, but most examples only look at it from a simple one class approach.我已经搜索了使用 PDO 进行异常处理的最佳实践,但大多数示例仅从简单的一类方法中查看它。

If I'm using controllers and a repo in an ORM type model, where should the various try/catch, and throw blocks happen?如果我在 ORM 类型模型中使用控制器和存储库,那么各种 try/catch 和 throw 块应该在哪里发生?

A simplified example:一个简化的例子:

CONTROLLER: (creates repo object, fires off the loadProduct method, and loads the template)控制器:(创建 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));    
    }
}

Should the try/catch blocks be put in the controller, and throw the exception if execute() returns nothing?是否应该将 try/catch 块放入控制器中,并在execute()返回任何内容时抛出异常? Throw a separate exception if the $Pdo->prepare() method doesn't fire?如果$Pdo->prepare()方法没有触发,则抛出一个单独的异常?

In general, exceptions handling policy is very simple.一般来说,异常处理策略非常简单。 Especially with PDO.尤其是 PDO。 Because PDO throws one only in case of serious malfunction and there is little sense in continuing execution - so, just a default halt is okay.因为 PDO 只有在严重故障的情况下才会抛出一个,并且继续执行几乎没有意义——所以,默认暂停就可以了。

So, for the average part of code, be it model, repository or whatever, no dedicated handling required at all.因此,对于代码的平均部分,无论是模型、存储库还是其他任何东西,根本不需要专门的处理。

Only in certain places for which you have a scenario for the failed query, try-catch have to be used.只有在某些地方,您有查询失败的场景,才必须使用 try-catch。 Most used scenario is a transaction rollback.最常用的场景是事务回滚。 So, if you have transaction, you may wish to wrap it in try and then rollback in catch.因此,如果您有事务,您可能希望将其包装在try ,然后在catch.回滚catch.

To answer a clarification in comments:要回答评论中的澄清:

That's two essentially different scenarios:这是两个本质上不同的场景:

  • There is nothing exceptional if SELECT can't find a product.如果 SELECT 找不到产品,也没什么特别的。
  • While if INSERT somehow creates an invalid SQL query, it's indeed a catastrophe.如果 INSERT 以某种方式创建了无效的 SQL 查询,那确实是一场灾难。

and they need different handling.他们需要不同的处理方式。

For the first case you don't need no exceptions at all, it's regular behavior.对于第一种情况,您根本不需要任何例外,这是常规行为。 Just have in your template a branch that says "Nothing found"只要在你的模板中有一个分支,上面写着“没有找到”

For the second one, create a custom exception handler, that logs error, sends 503, and shows generic 503 error page.对于第二个,创建一个自定义异常处理程序,记录错误,发送 503,并显示通用 503 错误页面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM