Desde hace un tiempo, he estado usando una función recursiva "tradicional" para aplanar matrices multidimensionales comoel paso por referencia no se trabaja con parámetros adicionales para array_walk_recursive, a menos que sea el desuso de llamadas en tiempo pasan por referencia
$baseArray = array(array('alpha'),
array('beta','gamma'),
array(),
array(array('delta','epsilon'),
array('zeta',array('eta',
'theta'
),
),
),
array('iota'),
);
a una simple matriz de 1-d.
Ayer por la noche, pensé que me gustaría echar un vistazo a array_walk_recursive() usando para ver si podía hacerlo más eficiente y más limpio.
Mi primer intento no tuvo mucho éxito:
function flattenArray($arrayValue, $arrayKey, &$flatArray) {
$flatArray[] = $arrayValue;
}
$flattenedArray = array();
array_walk_recursive($baseArray,'flattenArray',$flattenedArray);
pensé que debería funcionar, pero todo lo que tengo una serie de errores:
Warning: Cannot use a scalar value as an array in C:\xampp\htdocs\arrayTest.php on line 16
y un resultado de:
array(0) { }
mecanografía de tipo en mi función flattenArray() me dio
Catchable fatal error: Argument 3 passed to flattenArray() must be an array, integer given in C:\xampp\htdocs\arrayTest.php on line 16
Usando un cierre dio resultados idénticos
La única manera de que pudiera hacerlo funcionar (sin recurrir al uso de un mundial o una estática para mi flattenedArray) fue el uso de llamadas en tiempo pasar por referencia:
function flattenArray($arrayValue, $arrayKey, $flatArray) {
$flatArray[] = $arrayValue;
}
$flattenedArray = array();
array_walk_recursive($baseArray,'flattenArray',&$flattenedArray);
que produce el resultado correcto
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" }
pero me da una advertencia de no-inesperada
Deprecated: Call-time pass-by-reference has been deprecated in C:\xampp\htdocs\arrayTest.php on line 22
Sé que PHP es un lenguaje peculiar, pero parece un poco extremo. La documentación muestra claramente que el primer parámetro para array_walk_recursive es pass-by-reference, pero parece que los argumentos adicionales solo pueden pasarse por referencia en el tiempo de llamada. ¡Extraño!
versión de PHP 5.3.8 es
Cualquier sugerencia en cuanto a cómo puedo usar array_walk_recursive para aplanar mi matriz correctamente, sin obtener errores en desuso (además de la presentación de un informe de error).
EDITAR
P. S.
Soy consciente de que puedo pasar por alto este problema usando un cierre:
$flattenedArray = array();
array_walk_recursive($baseArray, function($arrayValue, $arrayKey) use(&$flattenedArray){ $flattenedArray[] = $arrayValue; });
var_dump($flattenedArray);
pero como este es necesario para una biblioteca que actualmente permite el uso con PHP 5.2.0, no es una opción práctica para utilizar una función que requiere una versión bastante más tarde de PHP
Puedo ver la lógica, aunque no estoy seguro de estar de acuerdo ... el argumento arrayValue se pasa a la función de devolución de llamada por referencia, lo que permite cambiar los valores de la matriz - cambiador de funciones (& $ arrayValue, $ arrayKey) { \t $ arrayValue. = 'TEST'; } array_walk_recursive ($ baseArray, 'changer'); var_dump ($ baseArray); –
El problema de la corrupción de la memoria me parece potencialmente grave ... no había visto ninguna evidencia de ello hasta que lo destacó –
Ciertamente creo que debería haber una nota formal que indique que no se puede usar la llamada por referencia con argumentos adicionales en la función de devolución de llamada como call_user_func(), no solo cualquier comentario que pueda agregar –