0

我到处都看到了这段代码的变体,包括许多 SO 帖子:

class db extends PDO {

    public function __construct( $dbconf ) {
        $options = array(
            PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_PERSISTENT => $dbconf['persist'] ? true : false
            );
        try {
            parent::__construct('mysql:host='. $dbconf['dbhost'] .';port=3306;dbname='. $dbconf['dbname'] .';' , $dbconf['dbuser'],
                $dbconf['dbpass'],
                $options);
        } catch (PDOException $e) {
            $this->myerror( $e->getMessage() );
            // echo 'Connection failed ... '. $e->getMessage();
        }
    }

    ...

    private function myerror( $error ) {
        echo 'Connection failed ... '. $error;
    }

}

该类实例化为$db = new db( $config );,如果连接有效,它会很好用,但PDOException如果连接失败,它似乎实际上不起作用。catch完全无法执行该功能$this->myerror(...)!而不是有用$e->getMessage()的说“连接失败......用户访问被拒绝”,我得到一个PHP Fatal error: Call to a member function myerror() on a non-object in /.../lib/pdo.class.php on line 16.

如果我注释掉 catch 中的第一行并取消注释echo,它会按预期工作,报告连接错误的原因。为什么消息在 catch 中可用,但在简单的myerror类函数中不可用?

这篇文章... PHP、PDO 和异常... 似乎适用,但解释不多。是catch (PDOException $e)过时或功能失调?我如何继续让它工作?

4

2 回答 2

1

原因是PDO::__constructobject在成功连接时创建。因此,当您调用父构造函数并且它失败时,您的对象不再存在。在这种情况下,您应该使用self::myerror()静态访问错误函数。

于 2013-06-24T06:41:37.190 回答
1

根本不应该有myerror()功能。数据库层几乎不需要它自己的错误处理程序。并且构造函数必须是

public function __construct( $dbconf ) {
    $dsn  = "mysql:";
    $dsn .= "host=".   $dbconf['dbhost'].";";
    $dsn .= "dbname=". $dbconf['dbname'].";";
    $dsn .= "port=".   $dbconf['dbport'].";";
    $dsn .= "charset=".$dbconf['dbcharset'];
    $options = array(
        PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES '.$dbconf['charset'],
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_PERSISTENT         => (bool)$dbconf['persist'],
    );
    parent::__construct($dsn, $dbconf['dbuser'], $dbconf['dbpass'],$options);
}
于 2013-06-24T06:49:42.040 回答