2013-08-08 6 views
5

Может ли кто-нибудь объяснить мне логику в этом поведении?Quirky __set() magic function

Рассмотрим следующую ситуацию:

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

Так

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

Прогнозный

prefix_myValue 

Actual

myValue 

Очевидно,

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

Работы, как ожидается, выводя

prefix_myValue 

Согласно __set описанию на http://www.php.net/manual/en/language.oop5.overloading.php#object.set

__set() запускается при записи данных в недоступных свойств.

Когда я создаю экземпляр EPPDomain в статическом методе класса EPPDomain, все защищенные свойства должны быть недоступны. Поэтому __set следует назвать, но это не

Я знаю, что это также говорит

собственности перегрузки работает только в контексте объекта. Эти магические методы не будут запускаться в статическом контексте. Поэтому эти методы не должны быть объявлены статическими. Начиная с PHP 5.3.0, предупреждение выдается, если один из методов перегрузки магии объявлен как статический.

Но у меня есть подавление, что он просто утверждает, что метод __set должен быть функцией класса и не должен быть статичным. Вот и все, и, похоже, это не имеет никакого отношения к ситуации, с которой я столкнулся.

Это ошибка или ожидаемое поведение?

+1

Было бы очень полезно, если бы вы могли * упростить * этот пример кода. Это слишком сложно, чтобы продемонстрировать свою точку зрения. – deceze

+0

Выполнено, извините, мой код намного сложнее, и я старался максимально упростить его. Наверное, не очень старался. Эта версия должна выглядеть лучше –

ответ

5

protected свойства доступного всего код в том же или унаследовать классы. Акцент делается на класс.

class Foo { 

    protected $bar; 

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

} 

Это работает отлично. Класс работает над экземпляром , он имеет доступ к его собственным свойствам. Речь идет не о «чужих случаях», а о классе.

Точка защищенных свойств заключается в том, что их присутствие или реализация должны относиться только к классу, который их определяет.Другой код не должен связываться с ними напрямую. Поскольку можно предположить, что класс знает, как справляться со своими собственными свойствами, классу доверяют манипулировать свойствами любого объекта его типа.

+1

Ничего, я не знал, что свойства private/protected будут доступны, даже если объект был создан в статическом заводском методе, принадлежащем тому же классу. Эффективно это заставляет разработчиков иметь фабричные методы в разных классах. Спасибо, что указали это –

0

Ожидается поведение, поскольку метод имеет доступ к защищенным (и даже частным) свойствам экземпляров его класса.