Ramon K.
Ramon K.

Reputation: 3502

About PHP Magic Methods __get and __set on inheritance

OBS: I coded directly here, beacause my code is much more complex.

If I code:

class SuperFoo {
    public function __get($name) {
        return $this->$name;
    }
    public function __set($name, $value) {
        $this->$name = $value;
    }
}

class Foo extends SuperFoo {
    private $bar = '';
}

$foo = new Foo();
$foo->bar = "Why it doesn't work?";
var_dump($foo);

Results in:

object(Foo) {
    ["bar":"Foo":private]=> 
        string(0) ''
}

And not in:

object(Foo) {
    ["bar":"Foo":private]=> 
        string(20) 'Why it doesn't work?'
}

Why this happen? I don't want to use an array to hold the attributes, because I need them declared as individual private members.

Upvotes: 5

Views: 2779

Answers (3)

WebDev
WebDev

Reputation: 11

If Foo::bar is private, Foo needs to override __get and __set. This is because SuperFoo can't access private members of Foo. The following code works but it's ugly:

class SuperFoo {
    public function __get($name) {
        return $this->$name;
    }

    public function __set($name, $value) {
        $this->$name = $value;
    }
}

class Foo extends SuperFoo {
    private $bar = '';

    public function __get($name) {
        return $this->$name;
    }

    public function __set($name, $value) {
        $this->$name = $value;
    }
}

The proper solution is to modify Foo::bar visibility to protected. Now SuperFoo has access to Foo::bar so there's no need to override __get and __set in Foo.

class SuperFoo {
    public function __get($name) {
        return $this->$name;
    }

    public function __set($name, $value) {
        $this->$name = $value;
    }
}

class Foo extends SuperFoo {
    protected $bar = '';
}

Check out the PHP Documentation on visibility

Upvotes: 1

webbiedave
webbiedave

Reputation: 48897

Your code should be resulting in a fatal error because you're trying to access a private property. Even before that, you should receive a syntax error because you haven't properly declared your functions. Hence, you're "resulting" var dump can never occur.

Edit:

You've edited your question. The reason it doesn't work is because bar is private to Foo (SuperFoo cannot access it). Make it protected instead.

Upvotes: 6

Vyktor
Vyktor

Reputation: 20997

__get($name) isn't called if object has attribute called $name, but it tries to use the attribute directly. And your attribute is private, thus error.

__set() is run when writing data to inaccessible properties.

__get() is utilized for reading data from inaccessible properties.

Upvotes: 3

Related Questions