@yanminibaev

Почему происходит при присвоении значения к свойству объекта в это?

Изучал php и наткнулся на один пример.
Почему если присвоить объекту свойство-массив , то он внутри переменной $test.
Если обычное свойство, то он вне переменной $test.
<?php
class Foo {
    public $test = [];
	
    public function & __get($name) {
        return $this->test[$name];
    }
	
	public function out() {
        return $this;
    }
}

$foo = new Foo();


$foo->arr[1] = 'one';
$foo->arr[2] = 'two';
$foo->str = 'three';

echo '<pre>';
print_r($foo->out());
print_r($foo->arr);

Вот результат:
Вывод print_r
Foo Object
(
    [test] => Array
        (
            [arr] => Array
                (
                    [1] => one
                    [2] => two
                )

        )

    [str] => three
)
Array
(
    [1] => one
    [2] => two
)

Вывод Var_Dump
object(Foo)#1 (2) {
  ["test"]=>
  array(1) {
    ["arr"]=>
    array(2) {
      [1]=>
      string(3) "one"
      [2]=>
      string(3) "two"
    }
  }
  ["str"]=>
  string(5) "three"
}
array(2) {
  [1]=>
  string(3) "one"
  [2]=>
  string(3) "two"
}


И еще вопрос по поводу ссылки & __get() , я знаю как работает ссылка в переменных, но в функциях не понятно
  • Вопрос задан
  • 90 просмотров
Решения вопроса 1
@Yan-s
php.net/references.return

$foo->arr[1] = 'one';

Сперва опишу первую часть этого выражения - $foo->arr :
Вы обращаетесь к свойству arr, но его не существует, поэтому вызов "перехватывается" методом __get. Он обращается ко свойству test используя в качестве ключа массива имя (arr) полученное в качестве параметра. После чего возвращает вам ссылку ( php.net/references.return ) на $this->test['arr'];

Вторая часть - [1] = 'one':
происходить обращение к элементу массива с индексом 1 полученного ранее свойства по ссылки. То есть запись $foo->arr[1] после разрешения ссылки эквивалентна $this->test['arr'][1] изнутри объекта. Далее идет присваивание строки, получается $this->test['arr'][1] = 'one';

Почему 'three' вне массива test?
Потому что $foo->str = 'three'; здесь вы не попадаете в __get(). Это не получение (get) свойства, а установка (set) его значения.

PS
Пример действительно мозголомный. Лучше такие штуки как возврат по ссылке да еще и в сочетании с магическим методом не использовать.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы