Php 异常处理的最佳实践:PDO+控制器和存储库
我已经搜索了关于在PDO中使用异常处理的最佳实践,但大多数示例仅从简单的单类方法中查看 如果我在ORM类型的模型中使用控制器和repo,那么各种try/catch和throw块应该发生在哪里 一个简化的例子: 控制器:创建repo对象,激发loadProduct方法,并加载模板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
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无关,因此您必须澄清您的问题。您是在询问如何在一般情况下使用异常吗?