【问题标题】:Error in object declaration when inheritance is used使用继承时对象声明错误
【发布时间】:2011-06-10 12:47:40
【问题描述】:

我一直在使用三个类。两个类扩展了第三个类 db。但问题是当我声明这些类的对象时,第二个对象被创建为第一个对象的克隆。提前感谢您的帮助。

        class db extends PDO {
    public function __construct() {
            echo "DB constructor called\n";
            ..
    }
        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();
}

$base_path = "../../";

require $base_path . 'config.php';
require $base_path . 'lib/class.db.php';
require $base_path . 'lib/Admin.php';
require $base_path . 'lib/Movie.php';

$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 (11) {
  ["uid":"Admin":private]=>
  NULL
  ["username":"Admin":private]=>
  NULL
  ["password":"Admin":private]=>
  NULL
  ["level":"Admin":private]=>
  NULL
  ["name":"Admin":private]=>
  NULL
  ["email":"Admin":private]=>
  NULL
  ["error":"db":private]=>
  NULL
  ["sql":"db":private]=>
  NULL
  ["bind":"db":private]=>
  NULL
  ["errorCallbackFunction":"db":private]=>
  NULL
  ["errorMsgFormat":"db":private]=>
  NULL
}
object(Admin)#2 (11) {
  ["uid":"Admin":private]=>
  NULL
  ["username":"Admin":private]=>
  NULL
  ["password":"Admin":private]=>
  NULL
  ["level":"Admin":private]=>
  NULL
  ["name":"Admin":private]=>
  NULL
  ["email":"Admin":private]=>
  NULL
  ["error":"db":private]=>
  NULL
  ["sql":"db":private]=>
  NULL
  ["bind":"db":private]=>
  NULL
  ["errorCallbackFunction":"db":private]=>
  NULL
  ["errorMsgFormat":"db":private]=>
  NULL
}

修改后的代码,请分析一下。当父::__construct($dsn, DB_USER, DB_PASSWORD, $options);在 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);
?>

【问题讨论】:

  • 你能用更小的系统重现这个问题吗?我想工作,但我最近没有太多空闲时间。如果您可以在较小的系统中观察到问题,那么它肯定是一个错误。由于整个代码不在这里,我无法确定。
  • @cem-kalyoncu 感谢您对我的问题表现出兴趣。我将在一个较小的系统中重新创建这种情况并在此处更新。请稍候。
  • @Cem Kalyoncu 我已将具有相同问题的较小代码放在stackoverflow.com/q/6310058/493796。请检查。

标签: php oop class constructor


【解决方案1】:

我没有发现任何问题——输出完全符合预期。因此,您所包含的文件中的其他地方一定是错误。这是独立测试代码:

<?php
class db extends PDO
{
    public function __construct()
    {
        echo "DB constructor called\n";
    }
}

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(Movie)#2 (3) {
  ["mid":"Movie":private]=>
  NULL
  ["title":"Movie":private]=>
  NULL
  ["slug":"Movie":private]=>
  NULL
}

所以请检查您的实际代码。也许(只是也许)你包含了错误的文件..或者第二类在另一个地方声明了(你可能正在编辑错误的文件)......

编辑: 亚历克斯,感谢您提供更多信息。我在您更新的代码中发现了问题:PDO::ATTR_PERSISTENT =&gt; true, -- 将true 更改为false 并查看差异:)

【讨论】:

  • 我已经在问题中添加了关于您的测试代码的修改代码。请检查一下。
  • @Alex:在您更新的代码中发现了问题:PDO::ATTR_PERSISTENT =&gt; true, - 将其更改为 false 并查看差异:)。附言-- 我相信你会自己找到关于这个属性的文档。
【解决方案2】:

它们不是克隆。它们都继承自 db 类,您没有对它们进行任何更改。它们不是克隆 - 它们只是完全相同。

【讨论】:

    【解决方案3】:

    如果要阻止 2 个 PDO 实例,请使用 Singleton pattern

    【讨论】:

    • 使用依赖注入模式或服务定位器会更好。
    猜你喜欢
    • 1970-01-01
    • 2021-07-07
    • 2016-07-20
    • 2019-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多