0

有人可以提供一种方法来处理Fatal error: Call to a member function prepare() on a non-object.

这是我的场景:

我有一个单例数据库类,它存储我的数据库详细信息并在请求时创建 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){}块来处理本质上是 a 的内容NullPointerException(如在 Java 中所见),但 PHP 不提供此类异常。相反,他们Fatal error: Call to a member function prepare()在非对象上发出。

所以我正在寻找的是一种在这种情况下处理这个错误的方法,而不是null每次都检查。

也许我错过了 PHP 中错误处理的基本概念,但我还没有找到关于这个主题的权威资源。

有什么建议么?

4

3 回答 3

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
        }
    }
于 2012-10-20T05:14:18.857 回答
0

您无法从 PHP 中的致命错误中捕获和恢复。您可以注册一个关闭函数来报告最后一个错误的详细信息,但与 Java 中的 finally 块不同。

此处有更详细的说明: 如何捕获 PHP 致命错误

我建议null每次都检查一下——与你的代码正在做的其他事情相比,这是一个廉价的调用。

于 2012-10-20T05:20:05.153 回答
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 */
}

换句话说,如果你问我,当对象的方法依赖于正常运行时,如果它无法实例化数据库连接,那么构造函数应该已经抛出RequestTranslatorSomeMeaningfulException

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一个很大的问题。我同意其他人的观点,性能损失可能可以忽略不计。

于 2012-10-20T07:02:09.133 回答