在较低层捕获PDOException并将其作为不同的异常重新投掷到上层

时间:2012-03-14 10:10:53

标签: php exception exception-handling pdo

您好我正在使用PDO库编写小型PHP框架。所以此刻我面临着异常捕捉问题。我希望在较低层捕获抛出的PDOException,并将其作为不同的异常对象重新抛出,并以这种方式将其冒泡到上层,隐藏用户的敏感错误信息,并为站点管理员等显示抽象的有用消息。在示例代码中(Mssql.class.php)我试图捕获异常并在无法建立与数据库的连接时重新抛出DBIException对象(例如,错误的主机名或用户名)。

在上层我尝试捕获DBIException(DBI.class.php)并重新抛出它 作为CoreException对象。在最后一层(SystemLoader.class.php)我试图捕获CoreException并打印相应的消息。从代码中可以看出,主要初始化类(SystemLoader.class.php)和init()方法是从index.php执行的,但是如果在较低层发生PDOException错误,我得到致命错误:未捕获异常'PDOException'而不是带有消息的CoreException “系统无法加载指定的资源”,正如我所料。但是如果我在try.catch块之间的index.php中放入System :: init(),则会捕获异常,但不会捕获DBIException或CoreException PDOException。

看起来捕获机制在某种程度上没有响应try ... catch块在较低级别,另一件事是我不想在index.php文件中使用try ... catch块我只是我想让这个文件结构变得复杂。我在互联网上阅读了很多信息并理解了异常处理的概念,但此刻我不知道我在哪里做错了。我应该在SystemLoader.class.php中设置自定义异常处理程序还是使用其他技术

的index.php

<?php
    require_once("SystemLoader.class.php");
    System::init();                   //initializing system params and other stuff
?>

SystemLoader.class.php

<?php
    require_once("DBIException.class.php");

    class SystemLoader
      {
        static function init()
          {
            try
               {
                 DBI::loadDBDriver("mssql");    //trying to load DB driver
               }
            catch(CoreException $e)
               {
                 echo "System couldn't load specified resources";
               }
         }
      }
?>

DBI.class.php

<?php

require_once("CoreException.class.php");

class DBI
  {    
    private $dbh;

    public static function loadDBDriver($dbDriver)
      {
        if($dbDriver = "mssql")
          {
            try 
               {
                 return new Mssql;
               } 
            catch (DBIException $e) 
               {
                 throw new CoreException($e)
               }
          }
        elseif($dbDriver = "mysql")
          {
            try 
               {
                 return new Mysql;
               } 
            catch (DBIException $e) 
               {
                 throw new CoreException($e)
               }
          }
      }

    public function setDBHandle($dbh)
     {
        $this->dbh = $dbh;
        $this->dbh->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_EMPTY_STRING);
        $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
     }
 }

Mssql.class.php

<?php
    require_once("DBIException.class.php");

class Mssql extends DBI
  { 
    public function __construct()
      {
       try 
          {
             $dbh=new PDO("dblib:host=192.168.0.1;Database=dbName", "user", "pass");
             parent::setDBHandle($dbh);
          }
       catch(PDOException $e)         //PDOException is not catched at this point
         {
             throw new DBIException($e);    /re-throw as new Exception object
         }
      }
  }
?>

CoreException.class.php

<?php
   class CoreException extends Exception {}
?>

DBIException.class.php

<?php
   class DBIException extends Exception {}
?>

0 个答案:

没有答案