【问题标题】:Best practice for exception handling: PDO + controllers & repositories异常处理的最佳实践:PDO + 控制器和存储库
【发布时间】:2013-11-05 19:18:47
【问题描述】:

我搜索了有关使用 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');
    }
}

模型/存储库:

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() 方法没有触发,则抛出一个单独的异常?

【问题讨论】:

  • 你想要什么例外?
  • 我又要问了。为什么要扔?你对它有什么期望?你的进一步情况是什么?好吧,假设你抛出了一个异常,不管在哪里。下一步是什么?
  • 澄清一下,我正在寻找的主要用例如下:用户查看产品或将商品添加到他们的购物车。这些操作需要通过控制器 -> repo 方法调用来访问数据库。如果出现问题(SELECT 找不到产品,INSERT 以某种方式创建了无效的 SQL 查询,或者该行已经存在等),它将将该错误吐回我可以在模板中显示的位置,以便用户知道什么发生了。示例:“抱歉,不存在此类产品”或“抱歉,此商品已在您的购物车中”。
  • 谢谢。我已经更新了答案
  • 购物车INSERT 应仅包含有效参数,即orderNum、SKU、数量、颜色、尺寸等。您的应用程序应确保仅将有效参数添加到查询中。

标签: php exception pdo orm


【解决方案1】:

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

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

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

回答 cmets 中的澄清:

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

  • 如果 SELECT 找不到产品,没有什么异常。
  • 虽然 INSERT 以某种方式创建了无效的 SQL 查询,但这确实是一场灾难。

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

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

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

【讨论】:

  • 你能澄清一下抛出代码的去向吗? try/catch 和 throw 是否完全在 repo 中?
  • 好吧,手动投掷与PDO无关,所以你必须澄清你的问题。您是在询问学习如何使用一般异常?
猜你喜欢
  • 1970-01-01
  • 2018-01-03
  • 1970-01-01
  • 1970-01-01
  • 2017-05-11
  • 2013-05-09
  • 2011-11-10
  • 1970-01-01
  • 2013-04-22
相关资源
最近更新 更多