问题
I have create three classes. One class is db which extends from PDO. Other two class extends from the db class. But the problem is when I initialize objects of these sub classes the second object is created as clone of the first object. Thanks in advance for any help.
<?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);
?>
Here is the output of the above. Please note the type of objects shown in the output.
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
}
When the parent::__construct($dsn, DB_USER, DB_PASSWORD, $options); in the db class is removed the issue will disappear.
回答1:
You have PDO::ATTR_PERSISTENT => true,
and you are attempting to create 2 PDO objects with the same DSN string. This tells PDO to return already established connection when you do $movieObj = new Movie();
instead of creating new one.
Solution in your case:
PDO::ATTR_PERSISTENT => false,
Useful link: Connections and Connection management
When the parent::__construct($dsn, DB_USER, DB_PASSWORD, $options); in the db class is removed the issue will disappear. Yes, because the actual PDO object will not be created in this case.
回答2:
First off, this seems like a bug, and it's probably due to how the PDO class internally handles persistent connections. That is, PHP shouldn't return the wrong extended class, but probably is because the core PDO driver was not designed with extending it in mind.
I searched for bugs on bugs.php.net, and there are some listed. (e.g., search for "pdo extend persistent") See #47407 for something similar.
All that said, it seems like a bad design on your part. Your classes should take a handle to an existing PDO object:
$db = new DB();
$movie = new Movie($db);
This will work around the PHP bug, but just as important... it's better designed.
来源:https://stackoverflow.com/questions/6310058/error-in-object-declaration-when-pdo-class-is-extended