扩展 PDO 的类 -parent::__construct 不起作用,但创建新的 PDO 可以

发布于 2024-12-18 01:00:43 字数 881 浏览 0 评论 0原文

我正在尝试编写 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:: 行,它就可以工作。

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

谢谢你!

I am trying to write a PDO wrapper but I'm having some problems with the constructor. Ideally, I would like to call the parent's constructor but, for some reason, that is not working. I tried (to test) to check if creating a new PDO and that does work, which I find most confusing.

Here is my code:

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();;
        }


    }
}

It works if I replace the parent:: line with $this->dbconn = new PDO($dsn, $user, $pw);

I believe that the "correct/elegant" way to do it is to use the parent:: syntax so I would like to know why that is not working/how I can fix it. Anyone can help?

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

如梦 2024-12-25 01:00:44

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

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 作为参数传递,但您不能对子类执行此操作。

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

That's not how you use constructors, as they don't return anything. Try the following instead:

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();;
    }
}

NOTE: You may still run into issues, as your constructor doesn't accept the same arguments as the PDO constructor. One of the tenets of OOP is that of equivalence, as embodied in the Liskov Substitution Principle, which means that the protocol (public API) of a subclass should be a strict superset of its superclass. The reason this is important is that if the subclass has an API that differs from the one presented by the class it inherits from, then it can't be used to substitute for the superclass in all cases.

For example, how would you use your subclass to connect to a PostgreSQL database or use a SQLite file instead of using mysql? The PDO superclass can work with all three, along with other database back ends, by virtue of the fact you can pass a DSN in as an argument, but you can't do that with your subclass.

However, all this is getting into aspects of computer science and is drifting off topic somewhat ;)

很酷又爱笑 2024-12-25 01:00:44

__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);

就是您需要的整个构造函数

__construct() doesn't have a return value and when you extend a class your custom one is of the type of the extended one. This means (in your case) an object of db is also an object of PDO

At all

$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);

Thats the whole constructor you need

金橙橙 2024-12-25 01:00:44

这个示例允许我简化软件中的连接字符串。

$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);
        }
     }
}

This example allows me to simplify connection string in my software.

$db = new epdo('MyDataBase');

It also allows for different server, username and password only and if required. Hope this helps:

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);
        }
     }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文