3

The below code does not work as intended.

$fruits = array('apple', 'orange', 'banana', 'cherry'); array_walk($fruits, function($a) { $a = ucfirst($a); }); var_dump($fruits); 

Why does this work when we pass the reference to an individual entry in the $fruits array.

array_walk( $fruits, function(&$a) { $a = ucfirst($a); } ); 

Note: I know array_map and foreach would work, but why does array_walk() not work?.

2
  • I don't think array_map or foreach would work, either. Unless you use references, you're not modifying the original element, you're modifying a copy. Commented Oct 30, 2013 at 19:24
  • If a reference isn't used then it is Call By Value. Commented Oct 30, 2013 at 19:24

4 Answers 4

5

Normally PHP uses Call by Value semantics when evaluating a function. This means that reassignments to parameters will not affect variable bindings in the caller. Because of this the assignment in the "non working" code has no affect outside the callback and thus does not alter the walked array.

However, when a function parameter is specified as &.. (as discussed in Passing By Reference) the semantics switch to Call by Reference. This means that variables in the caller can be altered through reassignment of the parameters. In this case the assignment to the local parameter reassigns the currently iterated array element through Call by Reference semantics and the code "works".

Now, array_walk "works" this way because it was designed to work with Call by Reference semantics. array_map, on the other hand, uses the return value of the callback.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! this should have more upvotes
3

If callback needs to be working with the actual values of the array, specify the first parameter of callback as a reference.

According to the docs: http://php.net/array_walk

1 Comment

@HasinHayder "The below code does not work as intended". My comment is to the first part in which he is not passing by reference... Reading the docs clearly answers his question.
3

With function($a) your passing a copy of $a to the function.

With function(&$a) your passing a reference to $a to the function. This way you can alter $a from within the function.

This is why array_walk is more memory efficient that array_map; you don't need an extra variable, you apply the function to each element on the original instead of returning the newly changed array.

Related question: Difference between array_map, array_walk and array_filter

Comments

0

In the first example $a is local variable. All changes out of the function are lost. By the way, reference point to real array and changes it but not local copy.

3 Comments

It's a local variable in both examples. The difference is whether the variable contains a copy or reference.
$a is a local variable in both cases; however the semantics are changed.
Yeah, I meant local copy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.