2011-06-10 130 views
0

我已创建三类。一类是从PDO扩展的db。其他两个类从db类扩展。但问题是当我初始化这些子类的对象时,第二个对象被创建为第一个对象的克隆。预先感谢您的帮助。错误时PDO类扩展

<?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 

}


当父:: __构建体($ DSN,DB_USER,DB_PASSWORD,$选项);在db类中被删除的问题会消失。

+0

如果您不满意提出的方案和需要持久连接,那么(好,我会建议它在任何情况下)根本不延长PDO和创建'db'类中PDO实例,而不是或通行PDO实例作为Admin/Movie类构造函数的参数。 – LazyOne 2011-06-10 18:55:16

回答

1

你有PDO::ATTR_PERSISTENT => true,,你正试图创建2 PDO使用相同的DSN字符串对象。这告诉PDO在您执行$movieObj = new Movie();而不是创建新连接时返回已建立的连接。

解决你的情况: PDO::ATTR_PERSISTENT => false,

有用的链接:Connections and Connection management

当父:: __构造($ DSN, DB_USER,DB_PASSWORD,$选项);在 DB类被删除的问题将 消失。 是的,因为在这种情况下不会创建实际的PDO对象。

+0

虽然这是一个正确的答案,但它只适用于PHP错误。这将导致每个对象有一个连接是浪费,并且会阻止跨请求使用任何持久连接(这可能是需要的)。 – Matthew 2011-06-10 18:27:48

+0

我完全同意“持续连接”的东西。最好的办法不是扩展PDO **,而是直接使用PDO(作为db处理程序),并且将db类声明为不带“extends”(例如'class db {...}') PDO对象作为类字段(在__construct()中创建或作为参数传递等)。 – LazyOne 2011-06-10 18:38:48

0

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

我搜索上bugs.php.net错误,并有部分上市。 (例如,搜索“pdo extend persistent”)请参阅#47407以了解类似的内容。

所有这一切说,好像你一个不好的设计。你的班应该采取句柄到现有的PDO对象:

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

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

+0

我想这不是一个错误,而是看看[这个解释](http://www.selfcontained。美国/ 2011/04/20/PHP-和一个抽象-单/)。 – hornetbzz 2011-07-08 05:41:22