Konstruktionsplan's avatar

Deep dark forest 🌲

function capMe($arr) {
  foreach ($arr as &$item) {
    $item = ucwords(strtolower($item));
  }
  return $arr;
}

This function transforms every first letter of the item in the array to a capital letter. (But it also makes them small in the first place).

I got that.

But I just do not understand what exactly makes:

&$item

"Parameter passing by reference" says Google. Could somebody explain it in a way that it also understands 🐒? Maybe with more, practical, examples? The more, the better!

Thanks! 💜

0 likes
6 replies
Snapey's avatar

without the &, then $item is a copy of the array attribute.

prefixed with &, the foreach loop gets a pointer to the element within the array, so when it is modified, it is the element within the original array that is changed and not a separate variable.

You won't find that you use this very often, but its useful to know it exists

if this did not exist then the function would need to look like;

foreach($arr as $key=>$item) {
  $arr[$key] = ucfirst($item);
}
1 like
automica's avatar

@konstruktionsplan

References allow two variables to refer to the same content. In other words, a variable points to its content (rather than becoming that content). Passing by reference allows two variables to point to the same content under different names.

$a = 1;
$b = &$a; // $b references the same value as $a, currently 1
$b = $b + 1; // 1 is added to $b, which effects $a the same way
echo "b is equal to $b, and a is equal to $a";

which outputs as

b is equal to 2, and a is equal to 2
1 like
Konstruktionsplan's avatar

First of all, thanks for the answer @snapey @automica !

$item = ucwords(strtolower($item));

Is the $item in the foreach then a reference? $item = is then an assignment of the variable...

It's pretty confusing. :(

Snapey's avatar
Snapey
Best Answer
Level 122

its hard to describe in words

when $one = $two then $one gets a copy of whatever was in $two when the instruction ran. The two things are independent variables and can each be changed without affecting the other.

when $one = &$two then $one is a pointer to $two. They are in the same space in memory and changing one also affects the other. you can consider $one being an ALIAS for $two

so, in your example foreach ($arr as &$item) $item is a pointer to the element within the array. When you process this variable in some way, you are also changing the array element. Without this you would be changing the copy of the array element and still have the job of putting that value back into the array.

Any clearer?

1 like
Konstruktionsplan's avatar

Hey @snapey

So it's become a little more understandable. I am looking for practical examples, but apart from examples that the numbers change a variable even outside a function, I don't find any practical use. Like:

function foo(&$var)
{
    $var++;
}

$a=5;
foo($a);
// $a is 6

When do you use it?

I think this is the better solution to the task I posted above:

function capMe($arr) {
  return array_map('ucfirst', array_map('strtolower', $arr));
}
Snapey's avatar

not very often!

sometimes when you have a large object in memory, it helps to pass the pointer to the object than duplicate the whole thing which can help with memory usage.

1 like

Please or to participate in this conversation.