Vladimir Hraban
Vladimir Hraban

Reputation: 3581

Quirky __set() magic function

Can anyone please explain me a logic in this behaviour?

Consider the following situation:

class EPPDomain
{
    protected $myField;

    public static function buildEPPDomain($fieldValue)
    {
        $me = new self();
        $me->myField = $fieldValue;
        return $me;
    }

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

class EPPDomainFactory
{
    public static function buildEPPDomain($fieldValue)
    {
        $me = new EPPDomain();
        $me->myField = $fieldValue;
        return $me;
    }
}

So

$dmn = EPPDomain::buildEPPDomain("myValue");
echo $dmn->myField;

Expected

prefix_myValue

Actual

myValue

Obviously,

$dmn = EPPDomainFactory::buildEPPDomain("myValue");
echo $dmn->myField;

Works as expected outputting

prefix_myValue

According to __set description on http://www.php.net/manual/en/language.oop5.overloading.php#object.set

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

When I create an instance of EPPDomain in a static method of EPPDomain class all protected properties are supposed to be inaccessible. Therefore __set should be called but it is not

I know it also says

Property overloading only works in object context. These magic methods will not be triggered in static context. Therefore these methods should not be declared static. As of PHP 5.3.0, a warning is issued if one of the magic overloading methods is declared static.

But I have an inpression that it just states that __set method should be a class member function and should not be static. That is it and it seems it has nothing to do with the situation I am facing.

Is that a bug or expected behaviour?

Upvotes: 5

Views: 115

Answers (2)

deceze
deceze

Reputation: 522076

A protected property is accessible to all code in the same or inheriting classes. The emphasis being on class.

class Foo {

    protected $bar;

    public function foo() {
        $foo = new self;
        $foo->bar = 'baz';
    }

}

This works just fine. The class is working on an instance of itself, it has access to its own properties. It's not about "foreign instances", it's about the class.

The point of protected properties is that their presence or implementation should only be relevant to the class that defines them. Other code shouldn't mess with them directly. Since one can assume that a class knows how to deal with its own properties, a class is trusted to manipulate properties of any object of its type.

Upvotes: 5

Ulrich Schmidt-Goertz
Ulrich Schmidt-Goertz

Reputation: 1116

It is expected behavior, because a method does have access to protected (and even private) properties of instances of its class.

Upvotes: 0

Related Questions