【问题标题】:Inheritance in PHP - Creating child instance and calling parent methodPHP中的继承-创建子实例并调用父方法
【发布时间】:2013-09-25 05:14:49
【问题描述】:

我有这样的事情:

class MyParent {
    protected static $object;
    protected static $db_fields;

    public function delete() {
           // delete stuff
    }


    public static function find_by_id($id = 0) {
        global $database;
        $result_array = self::find_by_sql("SELECT * FROM " . static::$table_name . " WHERE id=" . $database -> escape_value($id) . " LIMIT 1");
        return !empty($result_array) ? array_shift($result_array) : false;
    }

     public static function find_by_sql($sql = "") {
        global $database;

        // Do Query
        $result_set = $database -> query($sql);

        // Get Results
        $object_array = array();
        while ($row = $database -> fetch_array($result_set)) {
            $object_array[] = self::instantiate($row);
        }

        return $object_array;
    }

   private static function instantiate($record) {
        $object = self::$object;
        foreach ($record as $attribute => $value) {
            if (self::has_attribute($attribute)) {
                $object -> $attribute = $value;
            }
        }
        return $object;
    }


}


class TheChild extends MyParent {

    protected static $db_fields = array('id', 'name');
    protected static $table_name = "my_table";

    function __construct() {
        self::$object = new TheChild;
    }

}

$child= TheChild::find_by_id($_GET['id']);
$child->delete();

我明白了:Call to undefined method stdClass::delete() 指的是上面的最后一行。为了正确继承,我缺少哪一步?

【问题讨论】:

  • stdClass 与您的班级 Child 不同。你确定这是演示错误的确切代码吗?
  • 不要显示“喜欢”你拥有的代码,显示你拥有的代码。减少,如果你必须这样做,但不要让我们猜测 =)
  • 对不起,我试图展示一般原则。我真的很想知道上述方法是否可行;如果它是正确的,那么我知道问题更深。我会看看我是否可以添加更多。
  • 您几乎对制作 SSCCE 有了正确的想法,唯一的事情是您需要确保它重现错误。
  • 我添加了更精确的代码

标签: php class inheritance methods


【解决方案1】:

编辑:您更新的代码显示了一个完全不同的示例:

class MyParent {
    protected static $object;

    public function delete() {
           // delete stuff
    }
}


class TheChild extends MyParent {

    function __construct() {
        self::$object = new TheChild;
    }


}

$child = new TheChild;
$child->delete();

从“Child's”构造函数中调用“Child's”构造函数将导致无限循环:

 function __construct() {
        self::$object = new TheChild; // will trigger __construct on the child, which in turn will create a new child, and so on.
    }

也许 - 我不知道你想达到什么目标 - 你正在寻找:

 function __construct() {
        self::$object = new MyParent;
    }

ALSO 请注意,:: 表示法不仅仅是 -> 的不同版本 - 它是完全不同的。一种是静态访问,另一种是对实际对象实例的访问!

【讨论】:

  • “家长”似乎只是一个示例名称,因为自从您发布此答案以来,该问题已被编辑。
  • 对不起,这只是一个例子;我在上面重命名了。
【解决方案2】:

你从来没有真正实例化 TheChild 类,这应该由

$var = new TheChild();

TheChild 构造函数本身除外。

因此,静态 $object 字段永远不会受到影响(至少在您的示例中),因此影响它的字段(行 $object -> $attribute = $value; )会导致创建 stdClass 对象,如此交互式 PHP shell 会话中所示:

php > class Z { public static $object; }
php > Z::$object->toto = 5;
PHP Warning:  Creating default object from empty value in php shell code on line 1
php > var_dump(Z::$object);
object(stdClass)#1 (1) {
  ["toto"]=>
  int(5)
}

此对象没有delete 方法。

如前所述,实际创建TheChild 实例将导致无限递归。

你想做的大概是这样的:

class TheChild extends MyParent {

    protected static $db_fields = array('id', 'name');
    protected static $table_name = "my_table";

    function __construct() {
        self::$object = $this;
    }

}

【讨论】:

    猜你喜欢
    • 2021-08-28
    • 2020-12-21
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 2018-05-10
    • 2016-08-14
    相关资源
    最近更新 更多