TheLettuceMaster
TheLettuceMaster

Reputation: 15734

Inheritance in PHP - Creating child instance and calling parent method

I have something like this:

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();

I get this: Call to undefined method stdClass::delete() referring to the last line above. What step am I missing for proper inheritance?

Upvotes: 3

Views: 1482

Answers (2)

SirDarius
SirDarius

Reputation: 42899

You never actually instanciate the TheChild class, which should be done by

$var = new TheChild();

except in TheChild constructor itself.

So, the static $object field is never affected (at least in your example), so affecting a field to it (the line $object -> $attribute = $value; ) causes the creation of an stdClass object, as demonstrated in this interactive PHP shell session:

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)
}

This object does not have a delete method.

And as said before, actually creating a TheChild instance will result in an infinite recursion.

What you want to do is this, probably:

class TheChild extends MyParent {

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

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

}

Upvotes: 2

dognose
dognose

Reputation: 20899

Edit: Your updated code shows a COMPLETE different Example:

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();

Calling "Child's" Constructor from within "Child's" Constructor will result in an infinite loop:

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

Maybe - i dont know what you try to achieve - you are looking for:

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

ALSO note, that the :: Notation is not just a different Version for -> - it is completely different. One is a Static access, the other is a access on an actual object instance!

Upvotes: 1

Related Questions