Having done a bit of research, I eventually came across the answer to a question I was soon to ask here anyways; How do you work with arrays via the __get
and __set
magic methods in PHP? Whenever I was trying to set a value using something like $object->foo['bar'] = 42;
it seemed to silently discard it.
Anyways, the answer is simple; The __get
method simply needs to return by reference. And after tossing an ampersand in front of it, sure enough it works.
My question actually, is why? I can't seem to understand why this is working. How does __get
returning by reference affect __set
working with multidimensional arrays?
Edit: By the way, running PHP 5.3.1
In this particular case, __set
is not actually getting called. If you break down what it happening, it should make a bit more sense:
$tmp = $object->__get('foo');
$tmp['bar'] = 42
If __get
did not return a reference, then instead of assigning 42 to the 'bar' index of the original object, you're be assigning to the 'bar' index of a copy of the original object.
In PHP when you return a value from a function you can consider it making a copy of that value (unless it's a class). In the case of __get
unless you return the actual thing you want to edit, all the changes are made to a copy which is then discarded.
maybe more clear:
//PHP will try to interpret this:
$object->foo['bar'] = 42
//The PHP interpreter will try to evaluate first
$object->foo
//To do this, it will call
$object->__get('foo')
// and not __get("foo['bar']"). __get() has no idea about ['bar']
//If we have get defined as &__get(), this will return $_data['foo'] element
//by reference.
//This array element has some value, like a string:
$_data['foo'] = 'value';
//Then, after __get returns, the PHP interpreter will add ['bar'] to that
//reference.
$_data['foo']['bar']
//Array element $_data['foo'] becomes an array with one key, 'bar'.
$_data['foo'] = array('bar' => null)
//That key will be assigned the value 42
$_data['foo']['bar'] = 42
//42 will be stored in $_data array because __get() returned a reference in that
//array. If __get() would return the array element by value, PHP would have to
//create a temporary variable for that element (like $tmp). Then we would make
//that variable an array with $tmp['bar'] and assign 42 to that key. As soon
//as php would continue to the next line of code, that $tmp variable would
//not be used any more and it will be garbage collected.