Некоторое время я использовал "традиционную" рекурсивную функцию для сглаживания многомерных массивов, таких как
$baseArray = array(array('alpha'),
array('beta','gamma'),
array(),
array(array('delta','epsilon'),
array('zeta',array('eta',
'theta'
),
),
),
array('iota'),
);
в простой одномерный массив.
Прошлой ночью я решил посмотреть на использование array_walk_recursive(), чтобы увидеть, смогу ли я сделать его более эффективным и чистым.
Моя первая попытка была не очень успешной:
function flattenArray($arrayValue, $arrayKey, &$flatArray) {
$flatArray[] = $arrayValue;
}
$flattenedArray = array();
array_walk_recursive($baseArray,'flattenArray',$flattenedArray);
Я думал, что это должно работать, но все, что я получил, это серию ошибок:
Warning: Cannot use a scalar value as an array in C:\xampp\htdocs\arrayTest.php on line 16
и результат:
array(0) { }
Подсказка типа в моей функции flattenArray() дала мне
Catchable fatal error: Argument 3 passed to flattenArray() must be an array, integer given in C:\xampp\htdocs\arrayTest.php on line 16
Использование закрытия дало идентичные результаты
Единственный способ, которым я смог заставить его работать (не прибегая к использованию global или static для моего flattenedArray), это использование передачи по ссылке во время вызова:
function flattenArray($arrayValue, $arrayKey, $flatArray) {
$flatArray[] = $arrayValue;
}
$flattenedArray = array();
array_walk_recursive($baseArray,'flattenArray',&$flattenedArray);
который дает правильный результат
array(9) { [0]=> string(5) "alpha" [1]=> string(4) "beta" [2]=> string(5) "gamma" [3]=> string(5) "delta" [4]=> string(7) "epsilon" [5]=> string(4) "zeta" [6]=> string(3) "eta" [7]=> string(5) "theta" [8]=> string(4) "iota" }
но выдает неожиданное предупреждение
Deprecated: Call-time pass-by-reference has been deprecated in C:\xampp\htdocs\arrayTest.php on line 22
Я знаю, что PHP - причудливый язык, но это кажется немного экстремальным. Документация ясно показывает, что первый параметр array_walk_recursive передается по ссылке, но похоже, что дополнительные аргументы могут быть переданы по ссылке только во время вызова. Странно!
Версия PHP - 5.3.8
Любые предложения о том, как я могу использовать array_walk_recursive для корректного сглаживания массива, не получая при этом ошибок deprecated (помимо подачи сообщения об ошибке).
EDIT
P.S.
Я знаю, что могу обойти эту проблему, используя закрытие:
$flattenedArray = array();
array_walk_recursive($baseArray, function($arrayValue, $arrayKey) use(&$flattenedArray){ $flattenedArray[] = $arrayValue; } );
var_dump($flattenedArray);
но так как это требуется для библиотеки, которая в настоящее время позволяет использовать PHP 5.2. 0, это не практичный вариант использования функции, которая требует значительно более поздней версии PHP