Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP function array_replace(), why are the arguments passed by reference?

The function signature on PHP.net for array_replace() says that the arrays will be passed in by reference. What would be the reason(s)/benefit(s) to doing it this way rather than by value since to get the intended result you must return the finished array to a variable. Just to be clear, I am able to reproduce the results in the manual, so this is not a question on how to use this function.

Here is the function signature and an example, both from php.net.

Source: http://ca3.php.net/manual/en/function.array-replace.php

Function signature:

array array_replace ( array &$array , array &$array1 [, array &$... ] )

Example code:

$base = array("orange", "banana", "apple", "raspberry");
$replacements = array(0 => "pineapple", 4 => "cherry");
$replacements2 = array(0 => "grape");

$basket = array_replace($base, $replacements, $replacements2);
print_r($basket);

The above example will output:

Array
(
    [0] => grape
    [1] => banana
    [2] => apple
    [3] => raspberry
    [4] => cherry
)
like image 541
Jon Lyles Avatar asked Jun 22 '12 13:06

Jon Lyles


2 Answers

This function which calls php_array_merge_or_replace_wrapper which calls zend_hash_merge which in turn calls _zend_hash_merge etc. etc. etc. leads to an underlying memcmp() call which is probably ultimately why the arrays get passed into PHP's array_replace() by reference (because memcmp() requires them to be).

Arrays are one of the aspects of PHP that just seem to work and rarely get questioned, and I can kind of see why after doing a little digging.

like image 120
WWW Avatar answered Sep 23 '22 14:09

WWW


Well, the point is that _zend_hash_merge function is used not only by array_merge - but also by + operator (when both it operands are arrays).

And while there are some differences in processing, none of them actually can be attributed to the difference in requirements: as far as I know, no one writes + as &$arr + &$arr, it just makes no sense.

So I suppose it's just an error in documentation.

But one can come to this conclusion without analyzing the abyss of PHP internal code. ) Remember, we use &$array notation when we pass an array that can be (and most probably will) be changed - see, for example, array_splice() signature. And (this can be checked very easily) array_replace doesn't change its arguments - at least, at present. )

UPDATE: well, now I'm angry. If some PHP dev, God bless his soul, actually think that it's not a bug in documentation, let him/her explain why this:

array_pop(array('a' => 1));

... triggers a fatal error (Only variables can be passed by reference), and this...

array_replace(array('a' => 1), array('b' => 2));

... will just work, as nothing happened.

Or do we have two types of references in PHP now?

like image 45
raina77ow Avatar answered Sep 23 '22 14:09

raina77ow