Work with __get () by reference

With an example of such a class:

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

The Test instance will discard the output as such:

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

Is there a way to get additional information about what size of the array it is accessing by showing me (from the previous example) that the bar foo element and the hello bar element become targets?

+4
source share
3 answers

You cannot with the current implementation. To do this, you will need to create an array object (i.e.: an object that implements ArrayAccess ). Sort of:

 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']; 

Must output:

 foo is being accessed. ['bar'] is being accessed ['bar']['hello'] is being accessed world 
+3
source

No, you can’t. $myTest->foo['bar']['hello'] = 'world'; the next translation $myTest->__get('foo')['bar']['hello'] = 'world'; breaking them apart becomes

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

What you can do is create a derived ArrayAccess object. Where you define your own offsetSet() and return it from __get()

+1
source

Instead of returning an array, you can return an object that implements ArrayAccess . Objects are always returned and passed by reference. This pushes the problem, at least down.

+1
source

Source: https://habr.com/ru/post/1333297/


All Articles