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
Пример действительно мозголомный. Лучше такие штуки как возврат по ссылке да еще и в сочетании с магическим методом не использовать.