【问题标题】:How to use try-catch block for PDO如何为 PDO 使用 try-catch 块
【发布时间】:2012-03-04 08:50:15
【问题描述】:

在使用 try catch 块时,处理 PDO 错误的好方法是什么?

目前我有这样的事情:

BlogModel.php

   class BlogModel extends Model {
       public function save($id, $value) {
         $stmt = $this->getDb()->prepare('UPDATE setting SET name = :name WHERE id = :id');
         $stmt->bindParam(':id', $id);
         $stmt->bindParam(':name', $values);
         return ($stmt->execute() !== false) ? $id : false;
       }
   }

所以,在控制器 BlogController.php 中,我会做这样的事情:

<?php
class Blog extends Controller {

    public function comments()
    {
        $data = array();
        $model = new BlogModel;

        if ($model->save(2,'test')) {
                $data['result']['message'] = 'Settings saved';
                $data['result']['status'] = 'success';
        } else {
                $data['result']['message'] = 'Could not save the settings';
                $data['result']['status'] = 'error';
        }

        $view = new View("view.php", $data)
        $view->render();
    }
}
?>

这是我使用if 条件处理 PDO 错误的方式。将其转换为 try catch 块的体面方法是什么?我不想一直编码变量($data['result']['message']$data['result']['status'])。

是否可以在 catch 块中以某种方式添加“抛出异常”?

如果控制器中有很多 try catch 块,它看起来会很乱……对吧?

【问题讨论】:

  • 只是好奇:这是 CakePHP 吗?我说不出来。
  • @SimpleCoder 我自己写的 MVC ;)
  • 哦,整洁。我想直接使用 PDO 应该放弃这一点,而不是 Cake 的 db 接口。
  • 您可能会发现此 PHP 文档页面很有用 php.net/manual/en/class.pdoexception.php
  • 看看example here。你可以删掉所有无用的 html,但你明白了要点......

标签: php mysql pdo try-catch


【解决方案1】:

这里没有一个答案是错误的。但实际上这三个结合起来才是真正的答案。 你绝对应该设置

$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

正如 Cerad 所说。

从现在开始,关于数据库的每一个问题都会通过PDOException 类型的异常抛出。您不必像 ladar 所说的那样抛出自己的Exception,因为它没用。只需获取 ladar 代码并将其转换为

 ...
 $data = array();
 $model = new BlogModel;

    try{
      $model->save(2,'test');
      $data['result']['message'] = 'Settings saved';
      $data['result']['status'] = 'success';
    }catch(PDOException $e){
        $data['result']['message'] = 'Could not save the settings';
        $data['result']['status'] = 'error';
    }

并且不要自己扔任何东西。

那么调试 PDO 查询的一个非常好的方法是使用 Basic 链接的 catch 脚本,您可以再次找到 here

将这些东西结合在一起,您将拥有一种灵活、干净且​​易于调试的方法来捕获所有可能出现的错误。

【讨论】:

    【解决方案2】:

    怎么样:

    class BlogModel extends Model {
       public function save($id, $value) {
       ...
       if (!$stmt->execute()) {
            throw new Exception($stmt->errorInfo());
        }
       return $id;
    

    然后

     ...
     $data = array();
     $model = new BlogModel;
    
        try{
          $model->save(2,'test');
          $data['result']['message'] = 'Settings saved';
          $data['result']['status'] = 'success';
        }catch(Exception $e){
            $data['result']['message'] = 'Could not save the settings';
            $data['result']['status'] = 'error';
        }
    

    【讨论】:

    • +1 用于实际展示示例,而不仅仅是提供指向其他内容的链接
    • 不错的例子,谢谢.. 还有其他方法吗?
    【解决方案3】:

    您是否考虑过让 PDO 本身抛出异常而不是错误?

    $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    

    现在您可以消除可以显着减少代码的检查 PDO 错误。您可以添加一些 try/catch 块来捕获可以从约束冲突中恢复的异常。

    对于其余部分,只需在前端控制器的某个较高位置使用 Try/Catch 来捕获真正异常的异常。

    我的方法的唯一区别是,在 BlogModel 中,您只需:

    $stmt->execute();
    

    没有检查或其他任何事情。如果插入失败,只需让 PDO 抛出异常。然后你会在你的控制器中使用 try/catch as shown by ladar

    或者在我的情况下,如果我很确定插入永远不会失败,那么我只会在我的前端控制器中使用通用的 try/catch 块,而不是花时间尝试手动处理每个可能的异常。

    【讨论】:

    • 一种一般性的要求。你知道如何告诉 PDO 抛出异常而不是产生错误吗?基本上使用我在答案中显示的 setAttribute 方法。你是否明白,一旦 PDO 抛出异常,就不再需要检查以下错误:$stmt->execute();
    猜你喜欢
    • 1970-01-01
    • 2010-12-15
    • 2011-07-09
    • 1970-01-01
    • 2019-12-04
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    相关资源
    最近更新 更多