arrays - Can I assign value to target of reference in PHP? (I want to dereference)
I have a nested array, and I have a reference to an element within that array. I would like to be able to assign a value inside that array using my reference, but I can't see how to do that.
$arr = ['foo' => ['bar' => 'Hello World']];
$ref =& $arr['foo']['bar'];
var_export($arr);
// array (
// 'foo' =>
// array (
// 'bar' => 'Hello World',
// ),
// )
var_export($ref);
// 'Hello World'
$arr['foo']['bar'] = 'Test';
var_export($ref);
// 'Test'
The above works fine, but I now want to assign a new value to 'bar' using my reference:
&$ref = 'fooz';
PHP Parse error: syntax error, unexpected '&', expecting end of file in php shell code on line 1
I tried this, but it's a nope:
$ref =& 'fooz';
PHP Parse error: syntax error, unexpected ';', expecting :: (T_PAAMAYIM_NEKUDOTAYIM) in php shell code on line 1
And slightly worryingly, attempting this assignment appears to corrupt data:
$ref &= 'fooz';
var_export($ref);
// '@elh'
var_export($arr);
// array (
// 'foo' =>
// array (
// 'bar' => '@elh',
// ),
// )
Background: I have an array that may or may not be nested, and thus it's kind of hard to find the leaf-node where I want to assign things. So I had hoped to get a reference to said leaf-node, and then everything would be lovely.
I have PHP running on Linux Mint 20.2 (64bit).
$ php --version
PHP 7.4.3 (cli) (built: Jul 5 2021 15:13:35) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.3, Copyright (c), by Zend Technologies
Additional 20210907-1518: I am using the following function to set my reference:
function &getNestedArrayRef($array, array $keys) {
$key = array_shift($keys);
if (!is_null($key)) {
return getNestedArrayRef($array[$key], $keys);
}
return $array;
}
$ref = &getNestedArrayRef($arr, ['foo', 'bar]);
// The above _should_ be equivalent to:
$ref =& $arr['foo']['bar'];
^ it's entirely possible this isn't working as intended!
However, without it, it's kind of tricky to get a reference to an arbitrary point within the array without a literal reference.
Answer
Solution:
Think you are making life too complex.
Using the =&
makes $ref
a reference, so you dont need to use the &
reference idea on it again.
$arr = ['foo' => ['bar' => 'Hello World']];
$ref =& $arr['foo']['bar'];
$ref = 'Hi Boyo';
var_dump($arr);
RESULT
array(1) {
'foo' => array(1) {
'bar' => string(7) "Hi Boyo"
}
}
Second try, when real code was involved
$arr = ['foo' => ['bar' => 'Hello World']];
function &getNestedArrayRef(&$array, array $keys) {
$key = array_shift($keys);
if (!is_null($key)) {
return getNestedArrayRef($array[$key], $keys);
}
return $array;
}
$ref =& getNestedArrayRef($arr, ['foo', 'bar']);
$ref = 'Bye';
print_r($arr);
RESULT
Array
(
[foo] => Array
(
[bar] => Bye
)
)
You also need to pass the array to the function by reference
Source