Skip to content
Advertisement

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.

Advertisement

Answer

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

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement