Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does PHP optimize function arguments of array type, not explicitly passed by reference, when they are not modified?

Would the PHP engine optimize the second example to pass the $arr by reference?

function test1(array &$arr)
{
    $arr[] = 123;

    echo $arr[0];
}

function test2(array $arr)
{
    echo $arr[0];
}
like image 747
marsgpl Avatar asked Dec 16 '15 17:12

marsgpl


People also ask

Does PHP pass arrays by reference or value?

With regards to your first question, the array is passed by reference UNLESS it is modified within the method / function you're calling. If you attempt to modify the array within the method / function, a copy of it is made first, and then only the copy is modified.

Can we pass array as argument in PHP?

You can pass an array as an argument. It is copied by value (or COW'd, which essentially means the same to you), so you can array_pop() (and similar) all you like on it and won't affect anything outside. function sendemail($id, $userid){ // ... } sendemail(array('a', 'b', 'c'), 10);

Should you pass by reference in PHP?

The short answer is use references when you need the functionality that they provide. Don't think of them in terms of memory usage or speed. Pass by reference is always going to be slower if the variable is read only. Everything is passed by value, including objects.

What arguments are passed to a function in PHP?

PHP supports passing arguments by value (the default), passing by reference, and default argument values. Variable-length argument lists and Named Arguments are also supported. As of PHP 8.0. 0, the list of function arguments may include a trailing comma, which will be ignored.


1 Answers

PHP uses a mechanism called copy-on-write to avoid exactly the excessive copying of variables as long as it's unnecessary to do so. So even in your test2() example $array is not copied at all. If you'd modified $array inside the function, PHP would have copied the variable to allow modification. A detailed explanation of this mechanism can be found in the "Memory Management" chapter of the "PHP Internals Book". The following quote is from the "Reference-counting and copy-on-write" section:

If you think about the above for a bit, you’ll come to the conclusion that PHP must be doing an awful lot of copying. Every time you pass something to a function the value needs to be copied. This may not be particularly problematic for an integer or a double, but imagine passing an array with ten million elements to a function. Copying millions of elements on every call would be prohibitively slow.

To avoid doing so, PHP employs the copy-on-write paradigm: A zval can be shared by multiple variables/functions/etc as long as it’s only read from and not modified. If one of the holders wants to modify it, the zval needs to be copied before applying any changes.

The following two articles provide even more insight into this topic (both written by PHP core developers):

  • Johannes Schlüter: Do not use PHP references
  • Sara Golemon: You're being lied to

The first one even explains why using references just for performance reasons is most often a bad idea:

Another reason people use reference is since they think it makes the code faster. But this is wrong. It is even worse: References mostly make the code slower!

Yes, references often make the code slower - Sorry, I just had to repeat this to make it clear.

And the second one shows why objects are not really passed by reference in PHP5+.

like image 194
Stefan Gehrig Avatar answered Nov 10 '22 16:11

Stefan Gehrig