在PHP array_walk中传递引用第三个参数,没有警告

Ton*_*osa 6 php

有没有办法让这段代码在没有警告的情况下工作?

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)
Run Code Online (Sandbox Code Playgroud)

它工作,但它总是抛出此警告消息:

警告:第7行的path_to\index.php中不推荐使用call-time pass-by-reference

我认为从调用中删除&符应该足以使警告消失,但是,奇怪的是,如果我在"myFunction"中指定&,则"array_walk"不会形成第三个参数.为了使它工作,必须有一个&在电话中,但它会触发警告.

此外,作为一个临时解决方法,我试图将php.ini var"allow_call_time_pass_reference"设置为true,但我仍然收到警告......

我想知道可能有更好/首选的方法将用户定义的函数应用于带有传递引用参数的数组的每个元素.

irc*_*ell 14

简短的回答是你不能用数组走路做到这一点.但是,你确实有一些改变:

使用闭包(在PHP> = 5.3.0中可用):

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

创建一个过滤器迭代器(请注意,这可能是一种过度杀伤):

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);
Run Code Online (Sandbox Code Playgroud)

还有其他方法,但你追加的关键和价值确实使得绘制风格解决方案变得困难......

  • 在第一个解决方案中,参数顺序错误。它们应该是($ value,$ key) (2认同)

txy*_*oji 4

array_walk 的第三个参数不是通过引用传递的,因此这是行不通的。您可以使用对象方法作为回调,并将结果累积在对象中,而不是使用函数。

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'));
Run Code Online (Sandbox Code Playgroud)

或者您可以在回调函数中定义一个全局的。

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

两者都有效。