erfling
erfling

Reputation: 409

PDO:fetchClass not setting properties of parent class

So I've got three classes:

class GenericObject{
    private $parentThing
}

class MiddleObject extends GenericObject{
     private $middleThing
}

class ChildObject extends MiddleObject{
     private $childThing;    
}

and when I call pdoDatabaseThing->fetchAll(PDO::FETCH_CLASS, "ChildObject");, all of the properties defined in MiddleObject are null, though the properties defined in ChildObject and GenericObject are set as expected.

Is this expected behavior, or am I just missing a bug somewhere in my code? Is there a known workaround?

Upvotes: 1

Views: 480

Answers (1)

Progman
Progman

Reputation: 19546

It looks like this is an expected behavior. The ChildObject doesn't know about the private fields of the parent classes since they are private in that classes and thats the whole point. When the parent fields are at least protected you can set the field because the ChildObject class can use them as intended.

<?php
class ParentClass {
    protected $bar;

    public function getBar() {
        return $this->bar;
    }
}
class ChildClass extends ParentClass {
    private $foo;

    public function getFoo() {
        return $this->foo;
    }
}

$dbh = new PDO('mysql:host=localhost', 'test');
$stmt = $dbh->query('SELECT "someValue" AS foo, "another value" as bar');
$all = $stmt->fetchAll(PDO::FETCH_CLASS, 'ChildClass');
$obj = $all[0];
var_dump($obj);
var_dump($obj->getFoo(), $obj->getBar());

This will generate the following output:

object(ChildClass)#3 (2) {
  ["foo":"ChildClass":private]=>
  string(9) "someValue"
  ["bar":protected]=>
  string(13) "another value"
}
string(9) "someValue"
string(13) "another value"

If you change the visibility of the parents field to private you will get the situation you already have observed, having the parents private fields still be at NULL:

object(ChildClass)#3 (3) {
  ["foo":"ChildClass":private]=>
  string(9) "someValue"
  ["bar":"ParentClass":private]=>
  NULL
  ["bar"]=>
  string(13) "another value"
}
string(9) "someValue"
NULL

Upvotes: 3

Related Questions