Passing the third parameter by reference in PHP array_walk without warning

Is there a way to make this code without warning?

function myFunction($value, $key, &$array) { if (strlen($value)<=2) $array[] = $key.$value; } $a = array("aa", "bbb", "cc", "dd"); $resultA = array(); array_walk($a, 'myFunction', &$resultA); // now '$resultA' should contain: Array([0] => aa0 [1] => cc2 [2] => dd3) 

It works, but it always gives this warning message:

Warning: link follow timed out in path_to \ index.php on line 7

I thought that removing the ampersand from the call should be enough for the warning to disappear, and it is, but, oddly enough, array_walk does not execute the third parameter, if I just point to myFunction as well. To make it work, it must be in the call , but then it issues a warning.

Also, as a workaround, I tried setting php.ini var "allow_call_time_pass_reference" to true, but I'm still getting a warning ...

I am wondering if there could be a better / preferred method of applying custom functions to each element of the WITH array with the pass-by-reference parameter.

+6
php
source share
2 answers

The third parameter of array_walk is not passed by reference, so as not to work. Instead of a function, you can use the object method as a callback and accumulate the results in the object.

 Class myClass { public values; public function myCallback($value,$key) { if (strlen($value)<=2){ $this->values[] = $key.$value; } } } $a = array("aa", "bbb", "cc", "dd"); $obj = new myClass(); array_walk($a, array($obj,'myCallback')); 

or you can define a global value inside the callback function.

 function myFunction($value, $key) { global $array; if (strlen($value)<=2) $array[] = $key.$value; } 

both are valid.

+4
source share

The short answer is that you cannot do this with an array. However, you have a few changes:

Using closure (available in PHP> = 5.3.0):

 $myArray = array(); $callback = function ($key, $value) use (&$myArray) { if (strlen($value) <= 2) { $myArray[] = $key . $value; } }; array_walk($a, $callback); 

Create a filter iterator (note that this is most likely an overkill):

 class myFilterIterator extends FilterIterator { public function accept() { return strlen(parent::current()) <= 2; } public function current() { return parent::key() . parent::current(); } } $it = new myFilterIterator(new ArrayIterator($a)); $newArray = iterator_to_array($it); 

There are other ways, but you add a key and a value, which really makes it difficult to display style decisions ...

+13
source share

All Articles