Работа с __get () по ссылке

С примером такого класса:

class Test{ public function &__get($name){ print_r($name); } } 

Экземпляр Test отбросит результат как таковой:

 $myTest = new Test; $myTest->foo['bar']['hello'] = 'world'; //outputs only foo 

Есть ли способ получить дополнительную информацию о том, какое измерение массива будет доступно, показывая мне (из предыдущего примера), что элемент bar из foo и элемент hello bar нацелены?

Вы не можете с текущей реализацией. Чтобы это сработало, вам нужно будет создать объект массива (т. ArrayAccess Объект, реализующий ArrayAccess ). Что-то вроде:

 class SuperArray implements ArrayAccess { protected $_data = array(); protected $_parents = array(); public function __construct(array $data, array $parents = array()) { $this->_parents = $parents; foreach ($data as $key => $value) { if (is_array($value)) { $value = new SuperArray($value, array_merge($this->_parents, array($key))); } $this[$key] = $value; } } public function offsetGet($offset) { if (!empty($this->_parents)) echo "['".implode("']['", $this->_parents)."']"; echo "['$offset'] is being accessed\n"; return $this->_data[$offset]; } public function offsetSet($offset, $value) { if ($offset === '') $this->_data[] = $value; else $this->_data[$offset] = $value; } public function offsetUnset($offset) { unset($this->_data[$offset]); } public function offsetExists($offset) { return isset($this->_data[$offset]); } } class Test{ protected $foo; public function __construct() { $array['bar']['hello'] = 'world'; $this->foo = new SuperArray($array); } public function __get($name){ echo $name.' is being accessed.'.PHP_EOL; return $this->$name; } } $test = new Test; echo $test->foo['bar']['hello']; с class SuperArray implements ArrayAccess { protected $_data = array(); protected $_parents = array(); public function __construct(array $data, array $parents = array()) { $this->_parents = $parents; foreach ($data as $key => $value) { if (is_array($value)) { $value = new SuperArray($value, array_merge($this->_parents, array($key))); } $this[$key] = $value; } } public function offsetGet($offset) { if (!empty($this->_parents)) echo "['".implode("']['", $this->_parents)."']"; echo "['$offset'] is being accessed\n"; return $this->_data[$offset]; } public function offsetSet($offset, $value) { if ($offset === '') $this->_data[] = $value; else $this->_data[$offset] = $value; } public function offsetUnset($offset) { unset($this->_data[$offset]); } public function offsetExists($offset) { return isset($this->_data[$offset]); } } class Test{ protected $foo; public function __construct() { $array['bar']['hello'] = 'world'; $this->foo = new SuperArray($array); } public function __get($name){ echo $name.' is being accessed.'.PHP_EOL; return $this->$name; } } $test = new Test; echo $test->foo['bar']['hello']; 

Должен выводиться:

 foo is being accessed. ['bar'] is being accessed ['bar']['hello'] is being accessed world 

Нет, вы не можете. $myTest->foo['bar']['hello'] = 'world'; проходит следующий перевод: $myTest->__get('foo')['bar']['hello'] = 'world'; разбивая их по частям

 $tmp = $myTest->__get('foo') $tmp['bar']['hello'] = 'world'; 

Что вы можете сделать, так это создать производный объект ArrayAccess . Где вы определяете свой собственный offsetSet() и возвращаете это из __get()

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