5

PHP has some great functions (like array_walk) that allow you to process each element in an array. They're generally set up so you specify the array you want processed as the first parameter and a callback function to apply to each element as the second. These functions return booleans indicating success, not a copy of the modified array as you might expect. If you want the array to be modified, you have to pass the array in by reference like array_walk(&$my_array, 'my_callback');

However, in PHP 5.3 and above, if you pass by reference to function call you get a E_DEPRECATED error.

Does anyone know (if there exists) a correct way to use these functions to modify arrays without triggering the errors and without explicitly suppressing them? Are there newer alternatives to these old array processing functions.

3 Answers 3

7

Values are passed by reference implicitly in PHP >= 5.3 as determined by the function definition.

Function definition for array_walk():

bool array_walk ( array &$array , callable $funcname [, mixed $userdata = NULL ] )

Note &$array. As such, you do not need to explicitly pass the array by reference in the function call in PHP >= 5.3.

array_walk($my_array, 'my_callback');

However, you will need to ensure that the callback accepts it's value by reference accordingly (as demonstrated by nickb).

Also take a look at PHP 5.4 Call-time pass-by-reference - Easy fix available?

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

2 Comments

Ah... thanks, makes sense. Interesting nuance--you can't call by reference, but you can define a function/method with arguments which are referenced. php.net/manual/en/language.references.pass.php I still wish those functions returned copies of modified arrays or null instead of booleans!
Yes, exactly. Glad to help out.
6

Because you should be defining the callback to accept its parameter by reference to modify the array.

array_walk( $my_array, function( &$el, $key) { $el = $el / 2; });

So a quick example like this:

$my_array = range( 2, 10, 2);
array_walk( $my_array, function( &$el, $key) { $el = $el / 2; });
var_dump( $my_array);

Will output:

array(5) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  int(4)
  [4]=>
  int(5)
}

1 Comment

Thanks for the feedback, but Jasons answer below which added to your made the reference issue clearer. You still got an upvote from me though!
1

You can also pass an argument for the callback as the third parameter of array_walk. The problem is how to pass a reference as the callback argument. This used to be possible using the & prefix when calling array_walk. This is deprecated and subsequently made illegal. Defining the callback with a reference-type third parameter doesn't help here.

A workaround could be to pass a reference inside an array (&$var is allowed as argument of 'array'!) as the third argument and dereference the array in the callback to obtain the reference again, like so:

function cb(&$v, $k, $ar) {
  $v='bla'.$k;
  $ar[0]++;
}
$count=0;
$arr = array('sint'=>'er','kla'=>'aas','en'=>'zwartepiet');
array_walk($arr,'cb',array(&$count));
var_dump($arr,$count);

Which prints:

array(3) {
  ["sint"]=>
  string(7) "blasint"
  ["kla"]=>
  string(6) "blakla"
  ["en"]=>
  string(5) "blaen"
}
int(3)

When call-time references were still allowed, it used to be possible like so:

function cb(&$v, $k, $ref) {
  $v='bla'.$k;
  $ref++;
}
$count=0;
$arr = array('sint'=>'er','kla'=>'aas','en'=>'zwartepiet');
array_walk($arr,'cb',&$count);
var_dump($arr,$count);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.