扩展PDO的类 - parent :: __ construct不起作用,但是创建一个新的PDO

Dav*_*vid 5 php constructor pdo parent wrapper

我正在尝试编写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();;
        }


    }
}
Run Code Online (Sandbox Code Playgroud)

如果我更换parent::线路,它的工作原理$this->dbconn = new PDO($dsn, $user, $pw);

我相信"正确/优雅"的方法是使用parent::语法,所以我想知道为什么这不起作用/如何解决它.有人可以帮忙吗?

谢谢!

Gor*_*onM 5

这不是你如何使用构造函数,因为它们不返回任何东西.请尝试以下方法:

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();;
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:您可能仍会遇到问题,因为您的构造函数不接受与PDO构造函数相同的参数.OOP的一个原则是等价,如Liskov替换原则所体现的,这意味着子类的协议(公共API)应该是其超类的严格超集.这一点很重要的原因是,如果子类的API与它继承的类所呈现的API不同,那么在所有情况下都不能用它来代替超类.

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

然而,所有这些都涉及到计算机科学的各个方面,并且正在逐渐偏离主题;)


Kin*_*nch 5

__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);
Run Code Online (Sandbox Code Playgroud)

多数民众赞成你需要的整个构造函数