За последние 24 часа нас посетили 21037 программистов и 1466 роботов. Сейчас ищут 1008 программистов ...

Изменение приватного свойства вне класса

Тема в разделе "PHP для новичков", создана пользователем виталий032, 5 фев 2018.

  1. виталий032

    виталий032 Активный пользователь

    С нами с:
    31 янв 2014
    Сообщения:
    227
    Симпатии:
    30
    Адрес:
    Владивосток
    Всем привет.

    Заметил в коде автозагрузчика композера интересную вещь.
    Идет замена, как я понял, приватного свойства объекта вне его самого.

    Попробовал переложить на более простой лад, получилось вот так:
    PHP:
    1. class A
    2. {
    3.     private $foo = 9;
    4.  
    5.     public function getVar($var)
    6.     {
    7.         return $this->{$var};
    8.     }
    9. }
    10.  
    11. class B
    12. {
    13.     public function render()
    14.     {
    15.         $a = new A;
    16. //        C::changeVar($a);
    17.         call_user_func(C::changeVar($a));
    18.         echo $a->getVar(foo);
    19.     }
    20. }
    21.  
    22. class C
    23. {
    24.     public static function changeVar(A $a)
    25.     {
    26.         return Closure::bind(function () use ($a) {
    27.             $a->foo = 4;
    28.         },null,'A');
    29.     }
    30. }
    31.  
    32. (new B)->render();
    Т.е., через Closure я имитирую область видимости класса А и изменяю свойство 'foo';
    И, в конечном итоге при чтении свойства 'foo', отображается '4';

    Однако, если, закоментить вызов функции через call_user_func и вызвать C::changeVar($a), то значение свойства не изменится, как было равное 9, так и останется.

    Объясните, пожалуйста, почему так происходит?
     
  2. виталий032

    виталий032 Активный пользователь

    С нами с:
    31 янв 2014
    Сообщения:
    227
    Симпатии:
    30
    Адрес:
    Владивосток
    А, все, разобрался. При вызове C::changeVar($a) мы получаем объект closure, и чтобы анонимная функция исполнилась необходимо обратиться к объекту, как к методу.
    Следующее будет работать:
    PHP:
    1. class A
    2. {
    3.     private $foo = 9;
    4.  
    5.     public function getVar($var) {
    6.         return $this->{$var};
    7.     }
    8. }
    9.  
    10. $a = new A();
    11. (Closure::bind(function () {
    12.     $this->foo = 4;
    13. },$a,A::class))();
    14. echo $a->getVar(foo); // 4
     
    #2 виталий032, 5 фев 2018
    Последнее редактирование: 5 фев 2018