Php 类扩展PDO-parent::_构造不起作用,但创建新的PDO起作用

Php 类扩展PDO-parent::_构造不起作用,但创建新的PDO起作用,php,constructor,pdo,wrapper,parent,Php,Constructor,Pdo,Wrapper,Parent,我正在尝试编写一个PDO包装器,但构造函数有一些问题。理想情况下,我希望调用父级的构造函数,但由于某些原因,这不起作用。我试图(测试)检查是否创建了一个新的PDO,这是否有效,我发现这是最令人困惑的 这是我的密码: class db extends PDO { private $dbconn; public function __construct() { $dsn = 'mysql:dbname=' . MYSQL_DB . ';host=' . MYSQL

我正在尝试编写一个PDO包装器,但构造函数有一些问题。理想情况下,我希望调用父级的构造函数,但由于某些原因,这不起作用。我试图(测试)检查是否创建了一个新的PDO,这是否有效,我发现这是最令人困惑的

这是我的密码:

class db extends PDO {

    private $dbconn;

    public function __construct() {
        $dsn = 'mysql:dbname=' . MYSQL_DB . ';host=' . MYSQL_HOST;
        $user = MYSQL_USER;
        $pw = MYSQL_PW;
        try {
            $this->dbconn = parent::__construct($dsn, $user, $pw);
            $this->dbconn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            return $this->dbconn;
        }
        catch(PDOException $e) {
            echo 'Connection failed: ' . $e->getMessage();;
        }


    }
}
如果我用
$this->dbconn=new PDO($dsn,$user,$pw)替换
父项::
行,它就可以工作

我相信“正确/优雅”的方法是使用
parent::
语法,所以我想知道为什么这样做不起作用/我如何修复它。有人能帮忙吗


谢谢大家!

这不是使用构造函数的方式,因为它们不返回任何内容。请尝试以下操作:

public function __construct() {
    $dsn = 'mysql:dbname=' . MYSQL_DB . ';host=' . MYSQL_HOST;
    $user = MYSQL_USER;
    $pw = MYSQL_PW;
    try {
        parent::__construct($dsn, $user, $pw);
        $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }
    catch(PDOException $e) {
        echo 'Connection failed: ' . $e->getMessage();;
    }
}
注意:您可能仍然会遇到问题,因为您的构造函数不接受与PDO构造函数相同的参数。OOP的原则之一是等价性,如中所体现的,这意味着子类的协议(公共API)应该是其超类的严格超集。这一点很重要的原因是,如果子类的API与它从中继承的类所呈现的API不同,那么它不能在所有情况下都用来替代超类

例如,如何使用子类连接到PostgreSQL数据库或使用SQLite文件而不是使用mysql?PDO超类可以与这三个超类以及其他数据库后端一起使用,这是因为您可以将DSN作为参数传入,但不能与子类一起使用

然而,所有这些都进入了计算机科学的各个方面,并且有点偏离了主题;)

\uuu construct()
没有返回值,当您扩展一个类时,您的自定义类属于扩展类的类型。这意味着(在您的情况下)
db
的对象也是
PDO

根本

$dsn = 'mysql:dbname=' . MYSQL_DB . ';host=' . MYSQL_HOST;
$user = MYSQL_USER;
$pw = MYSQL_PW;
parent::__construct($dsn, $user, $pw);
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

这就是您需要的全部构造函数。这个示例允许我简化软件中的连接字符串

$db = new epdo('MyDataBase');
它还只允许在需要时使用不同的服务器、用户名和密码。希望这有助于:

class epdo extends PDO {
    public function __construct($dbname, $server='127.0.0.1', $username='usernamehere', $password='passwordhere') {
        parent::__construct("mysql:host=$server;dbname=$dbname", $username, $password);
        parent::setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

        // error reporting (only show errors on localhost)
        if( $_SERVER['SERVER_ADDR'] == '127.0.0.1') {
            parent::setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
        } else {
            parent::setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
        }
     }
}

构造不会返回任何内容。据我记忆所及,php没有静态构造函数。稍后我将检查“在成功时返回PDO对象”-但在
父对象中使用时不会,因为您已经在该对象中,因此将实例返回到自身是没有意义的。不过,语法
(new foo())->method()
在5.4rc1中应该是合法的。如果我没记错为什么要扩展PDO?你能补充什么?最好在包装器类中使用PDO对象作为依赖项