util (util) wrote in php_dev,
util
util
php_dev

getting reference to array value changes structure of array?

I'm surprised to see the var_dumps aren't identical. Is there any reason in practice to worry about the difference between them? Also, in general, is code like following frowned upon? I'm building up a data structure through reading rows from a database -- an array of arrays.
<?php

function &EmptyIfMissing(&$anArray, $key) {
  if (!array_key_exists($key, $anArray)) {
    $anArray[$key] = array();
  }
  return $anArray[$key];
}

$a = array();
$b = &EmptyIfMissing($a, 'B');
$b['C'] = 'C';
var_dump($a);
var_dump(array('B'=>array('C'=>'C')));
has output
array(1) {
  ["B"]=>
  &array(1) {
    ["C"]=>
    string(1) "C"
  }
}
array(1) {
  ["B"]=>
  array(1) {
    ["C"]=>
    string(1) "C"
  }
}
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 3 comments
I'm confused. What's the problem?

The outputs are identical, except that in the first, B is identified as a reference. $b is a reference to $a. In the second, it's manually defined, so it's not.

I would avoid returning (by reference) a portion of an array that was passed in by reference. It seems like it will cause quite a bit of confusion later when all manners of cascading variable changes occur.

You shouldn't be calling EmptyIfMissing as "&EmptyIfMissing", but it's probably a nitpick on my part. The function returns a reference already. Even if it didn't, you can't convert it to a reference just by prepending &. Your E_STRICT warnings might be throwing a notice about it, actually.

I was surprised to see it identified as a reference.

When I delete the & in front of my call to EmptyIfMissing, I find that my modification of the return value is not reflected in $a, that is, $a = array(B=>array()).

I'm hoping to avoid this pattern:
$b = EmptyIfMissing($a, 'B');
$b['C'] = 'C';
$a['B'] = $b; // Store it back
If I'm understanding this correctly, you want to create another array off an existing one if it doesn't already exist.

It's not necessary to do that, actually.

Let's say $a = array('a' => 123);
It's safe to do $a['b']['c'] = 456;
without prepping the $a to create $a['b'] = array(); first.