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

时间:2011-11-22 20:09:29

标签: php constructor pdo wrapper parent

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


    }
}

如果我将parent::行替换为$this->dbconn = new PDO($dsn, $user, $pw);

,则此功能正常

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

谢谢!

3 个答案:

答案 0 :(得分: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();;
    }
}

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

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

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

答案 1 :(得分: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);

这就是你需要的整个构造函数

答案 2 :(得分:2)

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

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