Ray
Ray

Reputation: 41448

Using functions like array_walk (and similar functions) to modify arrays in PHP >= 5.3

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.

Upvotes: 5

Views: 4468

Answers (3)

Roho
Roho

Reputation: 64

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);

Upvotes: 1

Jason McCreary
Jason McCreary

Reputation: 73021

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?

Upvotes: 7

nickb
nickb

Reputation: 59709

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)
}

Upvotes: 6

Related Questions