¿Cómo usar una variable para acceder a cierto elemento dentro de una matriz multidimensional?
-
06-07-2019 - |
Pregunta
Estoy usando matrices en PHP para modificar datos xml y volver a escribirlos. Esta es la estructura xml (simplificada para fines de demostración):
<docs>
<folder>
<name>Folder name</name>
<date>20.06.2009</date>
<folder>
<name>Subfolder1</name>
<date></date>
</folder>
<folder>
<name>Subfolder1</name>
<date></date>
</folder>
<file>
<name></name>
</file>
</folder>
<name></name>
<date></date>
</docs>
Usando este código , esto se analiza y transforma en una matriz multidimensional:
Array
(
[docs] => Array
(
[_c] => Array
(
[folder] => Array
(
[_c] => Array
(
[name] => Array
(
[_v] => Folder name
)
[date] => Array
(
[_v] => 20.06.2009
)
[folder] => Array
(
[0] => Array
(
[_c] => Array
(
[name] => Array
(
[_v] => Subfolder1
)
[date] => Array
(
[_v] =>
)
)
)
[1] => Array
(
[_c] => Array
(
[name] => Array
(
[_v] => Subfolder1
)
[date] => Array
(
[_v] =>
)
)
)
)
[file] => Array
(
[_c] => Array
(
[name] => Array
(
[_v] =>
)
)
)
)
)
[name] => Array
(
[_v] =>
)
[date] => Array
(
[_v] =>
)
)
)
)
Largo, lo sé. Pero ahora a la cuestión real. Si quiero agregar otro archivo a una subcarpeta llamada Subcarpeta2 en este caso, no es un problema hacerlo a mano cuando vea la estructura:
array_push($array['docs']['_c']['folder']['_c']['folder'][1], $newfile);
Ahora, cuando quiero hacerlo a través de la función que solo conoce una ruta a la carpeta (como docs / Folder name / Subfolder2 ), el algoritmo tiene que analizar la estructura de la matriz (verifique el nombre de cada [carpeta], verifique si hay una o más carpetas ['_c'] o [número]) - todo bien, pero no puedo encontrar una manera de crear una variable que tenga un " matriz " ruta para ese nuevo archivo.
Estaba pensando en algún lugar a lo largo de estas líneas:
$writepath = "['docs']['_c']['folder']...[1]"; // path string
array_push($array{$writepath}, $newfile);
Por supuesto, esta no es una sintaxis válida.
Entonces, ¿cómo puedo hacer una variable que contenga una ruta a través de los elementos de la matriz? Investigué un poco sobre w3c y php.net y no encontré información útil sobre matrices multidimensionales ...
Si alguien tiene alguna otra sugerencia con respecto a la estructura, transformación / manipulación xml, etc. por todos los medios, sé que está lejos de ser una forma suficiente de manejo de datos.
Gracias por cualquier aporte,
Erik
Editar: con respecto a la referencia, ¿es posible hacer referencia a la referencia? Como esa sería la forma de mover el 'puntero' a través de un conjunto de matrices? Algo como tal:
$pointer = &$array['docs'];
if (key($pointer) == '_c') { $pointer = &$pointer['_c']; }
else (
// create an array with '_c' key instead of empty '_v' array
)
Esta sintaxis no funciona.
Editar: la sintaxis funciona, no importa ... ¡Gracias por toda su ayuda, chicos!
Solución
Aunque esto no es exactamente una respuesta a su pregunta: en lugar del xml < - > código de matriz que podría usar < a href = "http://php.net/simplexml" rel = "nofollow noreferrer"> SimpleXML y sus capacidades XPath.
$ pathToParentelement es más o menos su $ writepath.<?php $xml = '<docs> <folder> <name>Folder name</name> <date>20.06.2009</date> <folder> <name>Subfolder1</name> <date></date> </folder> <folder> <name>Subfolder2</name> <date></date> <folder> <name>Subfolder3</name> <date></date> </folder> </folder> </folder> </docs>';
$doc = new SimpleXMLElement($xml); $pathToParentelement = '//folder[name="Subfolder3"]'; $element = $doc->xpath($pathToParentelement); isset($element[0]) or die('not found');
$newFolder = $element[0]->addChild("folder"); $newFolder->name = "Subfolder4.1"; $newFolder->date = date(DATE_RFC822);
// let's see the result echo $doc->asxml();
Otros consejos
Usar referencias podría ayudar.
En primer lugar, podría escribir una función que devuelva una referencia a la parte dada de la matriz para una cadena de ruta. Por ejemplo, get_path_array("Documents")
devolvería $array['docs']['_c']['folder']['_c']['folder'][1], $newfile)
<?php
function &get_path_array($path_str)
{
// your code to seek to seek the path in the array
return $result;
}
>?php
Ahora para agregar un elemento, podría hacer
array_push(get_path_array("docs/Folder name/Subfolder2"), $newfile);
¿Es eso lo que estabas buscando?
(Ver referencias php para más información)
Editar: en respuesta al comentario de Eric (un poco difícil de encajar en un comentario)
Creo que puede estar confundido acerca de cómo funcionan las matrices. Realmente no hay tal cosa como matrices multidimensionales en php, solo matrices que almacenan otras matrices. Por ejemplo,
<?php
$a = array(array(1,2,3), array(4,5,6));
$b = $a[1];
echo $b[0];
?>
Producirá " 4 " ;.
Tenga en cuenta que en el código anterior, $b
es una copia de $a[1]
, cambiar $array['doc']['path']
no afectará a <=>.
Sin embargo, usando referencias, esto puede hacerse funcionar:
<?php
$a = array(array(1,2,3), array(4,5,6));
$b = &$a[1]; // the & make $b a reference to $a[1]
$b[0] = 4242;
print_r($a);
?>
Salidas:
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[1] => Array
(
[0] => 4242
[1] => 5
[2] => 6
)
)
Por lo tanto, nunca es necesario generar la cadena <=>, solo usa un bucle para buscar la matriz correcta.