Поведение функции __get () в php - PullRequest
5 голосов
/ 25 апреля 2011

Я пытался найти последовательность, в которой магические методы вызываются в PHP. Поэтому написал очень простую программу

class testme
{
    public $var1;
    /*function __construct()
    {
        echo'<br/> Constructor called';
    }*/
      public function __set($name, $value)
    {
        echo'<br/> You are in sssset function';
    }
    public function __call($method,$arg)
    {
        echo '<br/> call method';
    }
    public function __get($name)
    {
        echo'<br/> You are in get function';
    }
    public function __isset($name)
    {
        echo'<br/> You are in isset function';
    }
    public function __unset($name)
    {
        echo'<br/> You are in unset function';
    }   
       function __destruct() {
       print "<br/>Destroying " . $this->name . "\n";
   }
}
$obj = new testme;
$obj->var1=5;

Ожидаемый результат был

You are in set function
Destroying 

Начало:

You are in get function
Destroying 

$obj->var1=5 Здесь я устанавливаю значение для класса var и почему оно вызывает __get. Что здесь не так?

Ответы [ 4 ]

8 голосов
/ 25 апреля 2011

Если вы сделаете var_dump на $name внутри __get, вы увидите, что оно содержит name.Функция __get фактически вызывается в __destruct.Это связано с тем, что $var1 является доступным членом, поэтому не вызывает функции __get или __set.

Из документации PHP:

Методы перегрузки вызываются при взаимодействии со свойствами или методами, которые не были объявлены или не видны в текущей области действия .Остальная часть этого раздела будет использовать термины «недоступные свойства» и «недоступные методы» для ссылки на эту комбинацию объявления и видимости.

Так как $var1 определен и общедоступен, вызов отсутствуетк магическим методам.

5 голосов
/ 25 апреля 2011

В вашем классе есть свойство $var1, поэтому __set не называется : оно вызывается только в том случае, если нет свойства с именем того, которое вы пытаетесь установить.

Удалите это общедоступное свойство $var1, и будет вызвано __set.


Тем не менее, даже после удаления этого свойства, __get все еще вызывается.

Если вы добавите эхо в конец вашего скрипта, вы увидите, что __get вызывается после, чем эхо - то есть после того, что кажется концом вашего скрипта.


И если вы посмотрите на свой метод деструктора:

function __destruct() {
    print "<br/>Destroying " . $this->name . "\n";
}

Вы видите, что этот деструктор пытается прочитать из несуществующего свойства - отсюда и вызов __get.

0 голосов
/ 25 апреля 2011

get вызывается деструктором ($this->name).В классе нет члена name, поэтому вызывается магический метод get.Magical set вызывается только если вы пытаетесь установить несуществующего участника.var1 существует, поэтому __set() вызывать не нужно.

Вы заявляете

Я пытался найти последовательность, в которой магические методы называются

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

0 голосов
/ 25 апреля 2011

__get / __set вызывается только в том случае, если открытая переменная недоступна. Попробуйте $obj->var2=5, и вы получите ожидаемый результат.

__get вызывается, потому что ваша команда уничтожения содержит неизвестный параметр $this->name

...