Finally I found a great explanation which helped me to understand this: What's the difference between passing by reference vs. passing by value?
As Daniel Pryden states:
In simplest terms:
- call by value means that you pass values as function arguments
- call by reference means that you pass variables as function arguments
In metaphoric terms:
- Call by value is where I write down something on a piece of paper and hand it to you. Maybe it's a URL, maybe it's a complete copy of
War and Peace. No matter what it is, it's on a piece of paper which
I've given to you, and so now it is effectively your piece of paper.
You are now free to scribble on that piece of paper, or use that piece
of paper to find something somewhere else and fiddle with it,
whatever.
- Call by reference is when I give you my notebook which has something written down in it. You may scribble in my notebook (maybe I
want you to, maybe I don't), and afterwards I keep my notebook, with
whatever scribbles you've put there. Also, if what either you or I
wrote there is information about how to find something somewhere else,
either you or I can go there and fiddle with that information.
In this case the notice "Only variables should be passed by reference" is still unjustified as we are only interested in retrieving the last value of the array. However the function end()
is defined like
mixed end ( array &$array )
The & sign which states passing by reference is there for a certain reason: end()
is not just returning the last element of an array, it also changes its internal pointer to the end. Therefore the array is modified.
If we only would return the last element of an array without touching the array there would be no need to pass the array by reference and we would not get this notice. But end()
is somehow the wrong function for that.
What if there is no justification for me getting this notice?
Note that also the function to be called might be defined wrong. In my case I hade a function defined like this:
/**
* Flatten an array by one level if only needing a certain key value from a sub array.
*
* Example: [["foo"=>"bar","foo"=>"cheese"]]
* Result: ["bar","cheese"]
*
* @param $array: The input array.
* @param $key: The key to flatupshift. Default is 0.
* @return $array: The result
*/
private function array_flatupshift(&$array, $key = 0) {
$a = [];
foreach ($array as $item) {
if (is_object($item)) {
array_push($a, $item->$key);
} else if (is_array($item)) {
array_push($a, $item[$key]);
}
}
return $a;
}
This is simply a wrong function definition. So if you also get notices like this: Check if the function you call is defined correctly. Passing by reference does not make sense here as the array being passed is not touched in any way. Therefore the function definition should be without the "reference &/":
private function array_flatupshift($array, $key = 0) {
There are some cases where you MIGHT use the error control operator if you know what you are doing. Therefore:
$string = "hi-dude";
echo @end(explode('-', $string));
... would be o.k. I guess is the result of explode is not needed anymore. However notice the drawbacks of suppressing all possible errors. Please correct me if I go wrong here.