Есть ли способ сделать этот код без предупреждения?
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)
Он работает, но он всегда выдает это предупреждение:
Предупреждение: переадресация вызова по времени устарела в path_to \ index.php в строке 7
Я думал, что удаление амперсанда из вызова должно быть достаточным, чтобы предупреждение исчезло, и это правда, но, как ни странно, «array_walk» не выполняет третий параметр, если я просто укажу & в «myFunction». Чтобы заставить его работать, в вызове также должен быть & , но затем он вызывает предупреждение.
Кроме того, в качестве временного решения я попытался установить для php.ini var "allow_call_time_pass_reference" значение true, но я все равно получаю предупреждение …
Мне интересно, может быть, есть лучший / предпочтительный метод применения пользовательских функций к каждому элементу массива WITH с параметром pass-by-reference.
Третий параметр 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'));
или вы можете определить глобальное значение внутри функции обратного вызова.
function myFunction($value, $key) { global $array; if (strlen($value)<=2) $array[] = $key.$value; }
оба действительны.
Короткий ответ заключается в том, что вы не можете сделать это с помощью массива. Однако у вас есть несколько альтернатив:
Использование замыкания (доступно в PHP> = 5.3.0):
$myArray = array(); $callback = function ($key, $value) use (&$myArray) { if (strlen($value) <= 2) { $myArray[] = $key . $value; } }; array_walk($a, $callback);
Создайте итератор фильтра (обратите внимание, что это, скорее всего, перебор):
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);
Есть и другие способы, но вы добавляете ключ и ценность, что действительно затрудняет отображение решений стиля …