Php 如何处理抽象类PDO中的错误

Php 如何处理抽象类PDO中的错误,php,oop,pdo,error-handling,Php,Oop,Pdo,Error Handling,我有一个用于更新、选择、删除和插入语句的抽象类。在我的数据库连接函数config.php中 function dbconnect() { $dbh; // database handler $host = 'localhost'; $user = 'root'; $pass = ''; $dbname = ''; $error;

我有一个用于更新、选择、删除和插入语句的抽象类。在我的数据库连接函数config.php中

function dbconnect() 
{
            $dbh; // database handler
             $host = 'localhost';
             $user =  'root';
             $pass =  '';
             $dbname = '';
             $error;


                // Set DSN
                $dsn = 'mysql:host=' . $host . ';dbname=' . $dbname;
                // Set options
                $options = array(
                    PDO::ATTR_PERSISTENT    => true,
                    PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION,
                    PDO::ATTR_EMULATE_PREPARES => false

                );
                // Create a new PDO instanace
                try{
                    $dbh = new PDO($dsn, $user, $pass, $options);
                }
                // Catch any errors
                catch(PDOException $e){
                    $error = $e->getMessage();
                }

               return $dbh;
           }     
注意,尝试捕捉错误

在我的抽象课上

   public function __construct() {
           $this->dbh = dbconnect();

       }

       public function query($query) {
           $this->stmt = $this->dbh->prepare($query);
       }

       public function bind($param, $value, $type = null) {
           if(is_null($type)) {
               switch (true) {
                   case is_int($value):
                       $type = PD0::PARAM_INT;
                       break;
                    case is_bool($value);
                        $type = PDO::PARAM_BOOL;
                        break;
                    case is_null($value);
                        $type = PDO::PARAM_NULL;
                        break;
                    default :
                        $type = PDO::PARAM_STR;
               }
           }
           $this->stmt->bindValue($param, $value, $type);
       }
 }
我的问题


在构造中,我连接到数据库,这也意味着我在这里捕获错误,在其他函数中,我没有错误处理,也没有返回其中的任何错误。在我的其他函数中有错误句柄吗?如果有,你建议我如何处理?总的来说,我仍然需要PDO和OOP,但我确实尝试以正确的方式做事。请告知

基本上,如果您无法连接到数据库,那么使用任何其他代码都没有意义,对吗?然后就是不捕捉异常。异常将冒泡,甚至阻止类被实例化,这意味着您不需要担心任何其他代码中的错误处理,因为它永远无法执行。这就是在构造函数中抛出异常的意义所在

例外情况是指发出异常情况的信号。如果您无法连接到数据库,这是一个非常特殊的情况。这会使整个数据库层不起作用。在这里,从数据库层抛出异常是正确的做法,因为数据库层是不可操作的,不能自行处理此问题。它需要向系统的其余部分发出信号,表示它无法工作,系统的其余部分需要决定在这种情况下该怎么做。在应用程序的更高层捕捉异常(如果有的话),并在那里显示一个错误页面以作出反应


对于常规查询期间可能发生的其他异常,同样的规则也适用。确定问题是否是可恢复的,在数据库类中捕获并处理它是否有意义,或者是否存在异常(同样,异常是永远不会发生的)意味着是时候放弃了。

您可能需要在数据库包装器的构造函数中处理异常的唯一时间是确保抛出特定类型的异常,并将其发送到应用程序-尽管我只能看到,如果您正在构建一个可以切换数据库连接的包装器,这一点很有用对象

例如,如果您使用的工厂模式可以创建
mysqli
PDO
对象,那么您可能希望构造函数捕获
mysqli::connect_error
(不是异常)和
PDOException
,并始终抛出公共
AppException
(扩展了
Exception

因此,在mysqli构造函数中,您可能只需要:

$dbConn = new mysqli($sHost, $sUsername, $sPassword, $sSchema, $iPort);

if($dbConn->connect_error) {
  throw new AppExecption(AppException::DB_CONNECT, $dbConn->connect_error);
}
在PDO包装构造函数中,您可能有:

try {
  $dbConn = new PDO($sDSN, $sUsername, $sPassword);
}

catch(PDOException $e) {
  throw new AppException(AppException::DB_CONNECT, $e->getMessage());
}

因此,您并不是真正在构造函数中处理PDO异常——只是将其转换为一种常见类型的异常,当它冒泡到应用程序时,可以以特定的方式进行处理,而不管您是在构造mysqli对象还是PDO对象。

当然,您必须为所有对象实现错误处理与数据库系统的交互。查询可能会抛出一个错误,而连接设置期间的错误处理不会捕获该错误。那么这有什么问题呢?按照您在连接设置例程中使用的样式进行操作,一切正常。您不必在该类中的每个方法中都这样做。在代码中使用该类时,添加一个try-catch块就足够了。您可能应该将
dbConnect()
函数移动到构造函数(或使其成为从构造函数调用的类的私有方法),并将
$error
作为类成员。然后,如果
$dbh
在您尝试连接时抛出异常,您可以使用getter方法检索错误信息。在我的一生中,我永远不会理解PHP用户的这种强烈愿望,即无目的地创建大量代码。只是为了方便起见,使用函数bind()是没有意义的(除了为limit参数使用占位符的可能性很小之外。不过,所有其他情况都是毫无用处的)。函数query()中没有任何点。拥有抽象的propotype是没有意义的。@CD001您似乎和所有PHP用户一样,混淆了DB访问类和模型类。前者不应该有这样的方法。而且后者应该不知道connectionEm,如果连接成功,那么OP所谈论的情况就会得到处理。是否要处理数据库层内常规查询期间引发的异常取决于遇到的异常情况。如果您确信可以在数据库层内以一种有用的方式处理错误,那么就在那里捕获并处理它。否则,还是让它冒泡吧。我可以连接到数据库deceze。@user你知道我要告诉你的关于异常和处理异常的要点了吗?@user No。我是说如果你得到错误,作为异常出现,就不要捕捉这些异常。例外情况注定会出现。这就是他们的目的。只有当你有建设性的计划如何处理它们时,才能抓住它们。仅仅记录一个错误,然后假装什么都没发生,这不是一个处理异常错误的建设性计划。我一直想知道,为什么PHP用户有如此强烈的信念,只有与数据库相关的错误才应该有一个格式很好的HTML错误页面。那么丑陋的PHP警告呢?他们不值得一个格式很好的页面?所以,就像其他PHP用户一样,你真的相信构建应用程序的人是唯一的用户,对吗?对于那些不是在建设而是想购买或阅读一些文章的简单用户来说呢?他们真的需要这些绒毛吗?那么一个可能会对这种漏洞感兴趣的黑客呢?我要说清楚——主要的反对意见是,你对错误处理的想法不清楚,而且似乎不合适。