2012-10-20 43 views
0

有人可以请提供一种方法来处理Fatal error: Call to a member function prepare() on a non-objectPHP/PDO:如何处理致命错误:调用成员函数prepare()在非对象

这是我的情景:

我有一个Singleton数据库类存储我的数据库的详细信息,并要求当创建一个PDO对象的实例。

我则有以下两类:

基类:

namespace lib\translator; 
use lib\database as db; 

class EntityTranslator { 
    protected $dbConn; 

    public function __construct() { 
     try { 
      $this->dbConn = db\Database::getInstance(); 
     } 
     catch(\PDOException $e) { 
      // do some error logging here 
     } 
    } 
} 

子类:

namespace lib\translator; 
use lib\entity as entity; 

class RequestTranslator extends EntityTranslator { 

    public function __construct() { 
     parent::__construct(); 
    } 

    public function createRequest() { 
     $request = new entity\Request(); 
     try { 
      $stmt = $this->dbConn->prepare("CALL createRequest()"); 
      $stmt->execute(); 

      $rowCount = $stmt->rowCount(); 
      if ($rowCount == 1) { 
       $row = $stmt->fetch(\PDO::FETCH_ASSOC); 

     // do stuff with the data here 
      } 
      return $request; 
     } 
     catch (\PDOException $pdoe) { 
     // do error logging here 
     } 
    } 
} 

现在,我不知道为何出现错误。当我的数据库连接不可用并且PDO对象实例化(通过调用db\Database::getInstance())抛出异常,导致变量$dbConn剩余null时,我试图处理非常罕见的情况。

我意识到,每次使用前都可以测试$dbConnnull。但正如我所说的,这应该是一个非常罕见的情况,实际上可能永远不会发生,所以我不认为每次检查null都是一个明智的性能选择。

我希望能够添加另一个catch(\Exception $ex){}块来处理本质上是NullPointerException(如Java所示),但PHP不提供这样的例外。相反,他们在非客体上发行Fatal error: Call to a member function prepare()

所以我在找的是一种处理这种错误的方法,对于这种情况,每次都不检查null

也许我错过了PHP中错误处理的基本概念,但我一直未能找到有关此主题的权威资源。

有什么建议吗?

回答

0

为什么您的应用程序无论如何都允许调用RequestTranslator::createRequest(),在实例化RequestTranslator时,您已经知道数据库连接是否已正确实例化?

应该不是你的应用程序逻辑是类似以下内容:

try 
{ 
    /* 
    * the following line should throw 
    * SomeMeaningfulException when it 
    * is unable to connect to the database 
    */ 
    $rt = new lib\translator\RequestTranslator(); 

    /* 
    * this line should not be reached 
    * if the above throws SomeMeaningfulException 
    */ 
    $rt->createRequest(); 
} 
catch(SomeMeaningfulException $e) 
{ 
    /* $rt database connection has not instantiated properly */ 
} 

换句话说,如果你问我的RequestTranslator构造应该已经抛出SomeMeaningfulException如果无法实例化时,数据库连接对象的方法依赖于正常:

class EntityTranslator { 
    protected $dbConn; 

    public function __construct() { 
     try { 
      $this->dbConn = db\Database::getInstance(); 
     } 
     catch(\PDOException $e) { 
      // do some error logging here 
      throw new SomeMeaningfulException('some meaningful message'); 
     } 
    } 
} 

如果由于某种原因不理想的话,我不明白为什么检查null很大的一个问题。我同意其他人的看法,表现的惩罚可能是可以忽略的。

+0

感谢您在回复中考虑您的情况。我认为你的解决方案是正确的,我的应用程序将从你的建议中受益。现在,将异常传递给链并处理它,然后才允许其他组件调用类方法,这样做更有意义。 – samazi

0
public function createRequest() { 
     $request = new entity\Request(); 
     try { 
      if(!is_null($this->dbConn)){ 
      $stmt = $this->dbConn->prepare("CALL createRequest()"); 
      $stmt->execute(); 

      $rowCount = $stmt->rowCount(); 
      if ($rowCount == 1) { 
       $row = $stmt->fetch(\PDO::FETCH_ASSOC); 

     // do stuff with the data here 
      } 
      return $request; 
      } 
     } 
     catch (\PDOException $pdoe) { 
     // do error logging here 
     } 
    } 
+0

正如我在我的问题中所述,我意识到我可以每次检查null,但是我相信这是一个不必要的性能打击,当我真的从不期望$ dbConn为null。我正在寻找一个不需要检查null的答案。 – samazi

0

您无法捕捉并从PHP中的致命错误中恢复。你可以注册一个关闭函数来报告最后一个错误的细节,但是没有像Java中的finally块。

更详细的解释在这里: How do I catch a PHP Fatal Error

我会建议每次检查null - 相比于其他的事情你的代码是干什么的,这是一种廉价的电话。

+0

感谢您的参考,我一直在寻找贯彻这样的东西。我实际上已经改变了我所有的代码,每次都检查null,但是我只希望PHP提供一个更好的方法来处理空指针异常。 – samazi

相关问题