扩展PDO类时对象声明出错


Error in object declaration when PDO class is extended

我创建了三个类。一个类是从PDO扩展而来的db。另外两个类是从db类扩展而来的。但问题是,当我初始化这些子类的对象时,第二个对象被创建为第一个对象的克隆。提前感谢您的帮助。

<?php
/** The Database Driver */
define('DB_DRIVER', 'mysql');
/** The name of the database */
define('DB_NAME', 'sample');
/** MySQL database username */
define('DB_USER', 'root');
/** MySQL database password */
define('DB_PASSWORD', 'root');
/** MySQL hostname */
define('DB_HOST', 'localhost');
class db extends PDO
{
    public function __construct()
    {
        echo "DB constructor called'n";
        $options = array(
            PDO::ATTR_PERSISTENT => true,
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
        );
        $dsn = DB_DRIVER . ":host=" . DB_HOST . ";dbname=" . DB_NAME;
        parent::__construct($dsn, DB_USER, DB_PASSWORD, $options);
    }
}
class Admin extends db
{
    private $uid, $username, $password, $level, $name, $email;
    public function __construct()
    {
        echo "Admin constructor called'n";
        parent::__construct();
    }
}
class Movie extends db
{
    private $mid, $title, $slug;
    public function __construct()
    {
        echo "Movie constructor called'n";
        parent::__construct();
    }
}

$adminObj = new Admin();
$movieObj = new Movie();
var_dump($adminObj);
var_dump($movieObj);
?>

这是上面的输出请注意输出中显示的对象类型

Admin constructor called
DB constructor called
Movie constructor called
DB constructor called
object(Admin)#1 (6) {
  ["uid":"Admin":private]=>
  NULL
  ["username":"Admin":private]=>
  NULL
  ["password":"Admin":private]=>
  NULL
  ["level":"Admin":private]=>
  NULL
  ["name":"Admin":private]=>
  NULL
  ["email":"Admin":private]=>
  NULL
}
object(Admin)#2 (6) {
  ["uid":"Admin":private]=>
  NULL
  ["username":"Admin":private]=>
  NULL
  ["password":"Admin":private]=>
  NULL
  ["level":"Admin":private]=>
  NULL
  ["name":"Admin":private]=>
  NULL
  ["email":"Admin":private]=>
  NULL

}


当父级::__construct($dsn,DB_USER,DB_PASSWORD,$options);删除db类后,问题将消失。

您有PDO::ATTR_PERSISTENT => true,,并且您正试图创建两个具有相同DSN字符串的PDO对象。当您执行$movieObj = new Movie();而不是创建新连接时,此命令会告诉PDO返回已建立的连接。

您的解决方案:PDO::ATTR_PERSISTENT => false,

有用的链接:连接和连接管理

当父::__construct($dsn,DB_USER、DB_PASSWORD、$options);在里面db类被删除,问题将消失是的,因为在这种情况下不会创建实际的PDO对象。

首先,这似乎是一个错误,可能是由于PDO类内部处理持久连接的方式。也就是说,PHP不应该返回错误的扩展类,但可能是因为核心PDO驱动程序在设计时没有考虑到扩展它。

我在bugs.php.net上搜索了一些bug,其中列出了一些。(例如,搜索"pdo-extend-persistent")类似内容请参见#47407。

尽管如此,对你来说,这似乎是一个糟糕的设计。您的类应该处理一个现有的PDO对象:

$db = new DB();
$movie = new Movie($db);

这将解决PHP错误,但同样重要的是。。。它设计得更好。