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

Php 异常处理的最佳实践:PDO+控制器和存储库,php,exception,pdo,orm,Php,Exception,Pdo,Orm,我已经搜索了关于在PDO中使用异常处理的最佳实践,但大多数示例仅从简单的单类方法中查看 如果我在ORM类型的模型中使用控制器和repo,那么各种try/catch和throw块应该发生在哪里 一个简化的例子: 控制器:创建repo对象,激发loadProduct方法,并加载模板 class ProductController { public function viewProduct($product_id) { $ProductRepository = new Prod

我已经搜索了关于在PDO中使用异常处理的最佳实践,但大多数示例仅从简单的单类方法中查看

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

一个简化的例子:

控制器:创建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');
    }
}
模型/存储库:

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方法未触发,则引发单独的异常?

通常,异常处理策略非常简单。尤其是PDO。因为PDO只有在出现严重故障时才会抛出一个,继续执行几乎没有意义——所以,默认暂停就可以了

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

只有在您有失败查询场景的某些地方,才必须使用try-catch。最常用的场景是事务回滚。所以,若您有事务,您可能希望将其包装在try中,然后在catch中回滚

要回答评论中的澄清,请执行以下操作:

这是两个本质上不同的场景:

如果SELECT找不到产品,则没有例外。 然而,如果INSERT以某种方式创建了一个无效的SQL查询,这确实是一场灾难。 它们需要不同的处理方式

对于第一种情况,您根本不需要任何异常,这是常规行为。只需在模板中找到一个分支,该分支未显示任何内容


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

您希望异常的原因是什么?我必须再次询问。你为什么要扔?你期望从中得到什么?你的进一步设想是什么?好吧,假设您抛出了一个异常,不管在哪里。接下来是什么?为了澄清,我正在寻找的主要用例如下:用户可以查看产品,也可以将项目添加到他们的购物车中。这些操作需要通过controller->repo方法调用访问数据库。如果出现错误,请选择“找不到产品”、“插入”以某种方式创建了无效的SQL查询,或者行已经存在,等等,它会将错误吐回模板中可以显示的位置,以便用户知道发生了什么。示例:抱歉,不存在此类产品,或者抱歉,此商品已在您的购物车中。谢谢。我已经更新了我的答案购物车插页应该只包含一个有效的参数,即orderNum、SKU、数量、颜色、大小等。您的应用程序应该确保只有有效的参数被添加到查询中。您能澄清抛出代码的位置吗?try/catch和throw是否完全在回购协议中进行?手动throw与PDO无关,因此您必须澄清您的问题。您是在询问如何在一般情况下使用异常吗?