How to use a variable to access certain element within a multidimensional array?
-
06-07-2019 - |
Question
I am using arrays in PHP to modify xml data and write it back. This is the xml structure (simplified for demonstration purpose):
<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>
Using this code, this is then parsed and transformed into a multidimensional array:
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] =>
)
)
)
)
Lengthy, I know. But now to the actual issue. If I want to add another file to a sub folder called Subfolder2 in this case, it's not a problem to do it by hand when u see the structure:
array_push($array['docs']['_c']['folder']['_c']['folder'][1], $newfile);
Now when I want to do it via the function that only knows a path to the folder (like docs/Folder name/Subfolder2), the algorithm has to analyze the array structure (check the name of each [folder], check if there is one or more folders ['_c'] or [number]) - all good, but I cannot find a way to create a variable that would have an "array" path for that new file.
I was thinking somewhere along these lines:
$writepath = "['docs']['_c']['folder']...[1]"; // path string
array_push($array{$writepath}, $newfile);
Of course this is not a valid syntax.
So, how can I make a variable that contains a path through the array elements? I did a bit of research on w3c and php.net finding no helpful info on multidimensional arrays...
If anyone has any other suggestions regarding structure, xml transformation/manipulation etc. by all means, I know it is far from sufficient way of data handling.
Thanks for any input,
Erik
Edit: Regarding the reference, is it possible to reference the reference? As that would be the way to move the 'pointer' through a set of arrays? Something as such:
$pointer = &$array['docs'];
if (key($pointer) == '_c') { $pointer = &$pointer['_c']; }
else (
// create an array with '_c' key instead of empty '_v' array
)
This syntax does not work.
Edit: The syntax works, never mind... Thanks for all your help guys!
Solution
Although this isn't exactly an answer to your question: Instead of the xml<->array code you could use SimpleXML and its XPath capabilities.
$pathToParentelement is more or less your $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();
OTHER TIPS
Using references might help.
You could firstly write a function that returns a reference to the given part of the array for a path string. For example, get_path_array("Documents")
would return $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
Now to add an element, you could just do
array_push(get_path_array("docs/Folder name/Subfolder2"), $newfile);
Is that what you were looking for?
(See php references for more info)
Edit: In reply to Eric's comment (a bit too hard to fit into a comment)
I think you may be confused about how arrays work. There isn't really any such thing as multidimentional arrays in php, just arrays that are storing other arrays. For example,
<?php
$a = array(array(1,2,3), array(4,5,6));
$b = $a[1];
echo $b[0];
?>
Will output "4".
Note that in the above code, $b
is a copy of $a[1]
, changing $b
won't affect $a[1]
.
However, using references, this can be made to work:
<?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);
?>
Outputs:
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[1] => Array
(
[0] => 4242
[1] => 5
[2] => 6
)
)
So there is never a need to generate the string $array['doc']['path']
, you just use a loop to seek the right array.