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];
}
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.
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);
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.
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.
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):
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+.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With