开发者

Pass-by-reference the third parameter in PHP array_walk, without a warning

Is there a way to make this code work without a 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 throws this warning message:

Warning: Call-time pass-by-reference has been deprecated in path_to\index.php on line 7

I thought that removing the ampersand from the call should be enough to make the warning disappear, and it is, but, strang开发者_运维技巧ely the "array_walk" doesn't acomulate the third parameter if I just specify the & in "myFunction". To make it work there has to be an & in the call too, but then it will trigger the warning.

Further, as a temorary workaround I have tried to set the php.ini var "allow_call_time_pass_reference" to true, but I still get the warning...

I'm wondering that may be there's better/preferred method to apply user-defined functions to each element of an array WITH a passed-by-reference parameter.


The short answer is that you can't do that with array walk. However, you do have some alterantives:

Using a 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 likely way 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're appending of key and value really makes things difficult for mapping style solutions...


The third parameter to array_walk isn't passed by reference so that's not going to work. Instead of a function, you can use an 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 could define a global inside the callback function.

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

both are valid.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜