Reputation: 16802
Say I have the following code:
<?php
class test implements ArrayAccess {
var $var;
function __construct()
{
$this->var = array(
'a' => array('b' => 'c'),
'd' => array('e' => 'f'),
'g' => array('h' => 'i')
);
}
function offsetExists($offset)
{
return isset($this->var);
}
function offsetGet($offset)
{
return isset($this->var[$offset]) ? $this->var[$offset] : null;
}
function offsetSet($offset, $value)
{
if (is_null($offset)) {
$this->var[] = $value;
} else {
$this->var[$offset] = $value;
}
}
function offsetUnset($offset)
{
unset($this->var[$offset]);
}
}
$test = new test();
$test['a']['b'] = 'zzz';
print_r($test->var);
What I'd want that to do is to display something like this:
Array
(
[a] => Array
(
[b] => zzz
)
[d] => Array
(
[e] => f
)
[g] => Array
(
[h] => i
)
)
What it actually displays is more like this:
Array
(
[a] => Array
(
[b] => c
)
[d] => Array
(
[e] => f
)
[g] => Array
(
[h] => i
)
)
ie. $test['a']['b']
is unchanged.
Any idea how I can make it changeable using that syntax? I could assign $test['a']
to a variable and then do $temp['b'] = 'zzz';
and then do $test['a'] = $temp;
but idk - that seems excessive.
Upvotes: 4
Views: 102
Reputation: 24576
The problem is that offsetGet
returns an array by value, i.e. a copy of the internal value. $test['a']['b'] = 'zzz'
operates on this copy, returned by $test['a']
.
But you can make offsetGet
return a reference instead:
function &offsetGet($offset)
{
$null = null;
if (isset($this->var[$offset])) {
return $this->var[$offset];
}
return $null;
}
Note that I had to modify the method body as well, so that return
is always followed by a variable, not an expression.
Output for 5.4.7 - 7.0.0rc2, hhvm-3.6.1 - 3.9.0
Array ( [a] => Array ( [b] => zzz ) [d] => Array ( [e] => f ) [g] => Array ( [h] => i ) )
You can even simplify it to:
function &offsetGet($offset)
{
return $this->v[$offset];
}
Because if you return non-existing variables by reference, they are implicitly created. And this way, you can create new nested elements like this:
$test['new']['nested'] = 'xxx';
Demo: https://3v4l.org/OSvuA
Upvotes: 1
Reputation: 4557
You are printing out the array from the class. Try this
$test = new test();
$data = $test -> var;
$data['a']['b']= 'ssss';
print_r($data) ;
Hope this help.
Upvotes: 0