PHP Array Assignment and References

This is a quick explanation of some more referencing quirks in PHP.

Let’s say you need to store an array in a specific variable so that another variable can be freed up and overwritten with different information.  [To clarify, this array may be very large and copying it would be detrimental to performance in this particular application. For small arrays, copying and not referencing may be preferable.]

The operation for referencing the array with a new variable is quite simple:

$array_goes_here =& $need_to_free_up_this_var;

The code above will reference the array to prevent PHP from making an unnecessary copy of the whole thing.

Now here’s what you have to avoid:

$need_to_free_up_this_var = array(); /* wrong! */

That might look reasonable, but if you think about it for a moment, you will see it is syntactically equivalent to this:

$new_array = array();
$need_to_free_up_this_var = $new_array; /* wrong! */

The new array is assigned by value, which will actually delete everything in $array_goes_here.  This gets a little bit confusing for anyone with a C++ background because the assign-by-value concept doesn’t exist for arrays in that language.  And of course, the & operator has a whole different meaning here.

How about this next one?  It makes sense in a PHP sort of way, doesn’t it?

$need_to_free_up_this_var =& array(); /* wrong! */

See the result for yourself:

Parse error: syntax error, unexpected ‘array’ (T_ARRAY)

Completing this process correctly in PHP requires a four-step procedure:

$new_array = array();
$array_goes_here =& $need_to_free_up_this_var;
$need_to_free_up_this_var =& $new_array;
unset( $new_array );

The call to unset() may be needed to avoid accidental re-use of the $new_array variable.

But if you absolutely have to do it in three lines of code, there is this alternative version of the same thing:

$array_goes_here =& $need_to_free_up_this_var;
unset($need_to_free_up_this_var);
$need_to_free_up_this_var = array();

The choice between those two versions depends on context.  Inside a simple loop, the latter syntax sometimes works better.  Consider this third pattern:

$large_array = array();
while ( $whatever ) {
	$array_builder = array();
	$array_builder['blob'] = some_big_function();
	$large_array[] =& $array_builder;
	unset( $array_builder );
}

Of course, that last example is a bit far-fetched because the same code simplifies down to this:

$large_array = array();
while ( $whatever ) {
	$large_array[] = array( 'blob' => some_big_function() );
}

Both of those last two patterns accomplish the same end result, but could have different benchmark performance in PHP depending on the size and type of the variables.

Use your own judgment and watch out for the “wrong” ways of doing this.

Leave a Reply

Your email address will not be published. Required fields are marked *