Я создал три класса. Один класс – это db, который простирается от PDO. Другие два класса простираются от класса 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
}
Когда parent :: __ construct ($ dsn, DB_USER, DB_PASSWORD, $ options); в классе db проблема исчезнет.
У вас есть PDO::ATTR_PERSISTENT => true,
и вы пытаетесь создать 2 объекта PDO с той же строкой DSN. Это говорит PDO возвращать уже установленное соединение, когда вы делаете $movieObj = new Movie();
вместо создания нового.
Решение в вашем случае: PDO::ATTR_PERSISTENT => false,
Полезная ссылка: Подключения и управление подключением
Когда parent :: __ construct ($ dsn, DB_USER, DB_PASSWORD, $ options); в классе db проблема исчезнет. Да, потому что фактический объект PDO не будет создан в этом случае.
Во-первых, это похоже на ошибку, и это, вероятно, связано с тем, как PDO-класс внутренне обрабатывает постоянные соединения. То есть, PHP не должен возвращать неправильный расширенный класс, но, вероятно, это связано с тем, что основной драйвер PDO не был разработан с учетом его расширения.
Я искал ошибки на bugs.php.net, и некоторые из них перечислены. (например, поиск «pdo extend persistent») См. # 47407 для чего-то подобного.
Все, что было сказано, кажется, что это плохой дизайн с вашей стороны. Ваши классы должны обращаться к существующему объекту PDO:
$db = new DB(); $movie = new Movie($db);
Это будет работать вокруг ошибки PHP, но так же важно … это лучше спроектировано.