Reputation: 251
I am having the following array
Array
(
[0] => Homework2 (1).java
[test2] => Array
(
)
[1] => space-art-hd-473771.jpg
[2] => Homework2.java
[3] => factura_oct_2013.pdf
[test] => Array
(
[0] => Homework2 (1).java
[1] => space-art-hd-473771.jpg
[2] => Homework2.java
)
[test3] => Array
(
[0] => Homework2 (1).java
[testintest] => Array
(
[0] => Homework2 (1).java
[1] => space-art-hd-473771.jpg
[2] => Homework2.java
)
[1] => space-art-hd-473771.jpg
[2] => Homework2.java
)
)
and I am trying to display an HTML nested list. So each child of the array should be a new UL in the parent UL. I have tried to get this recursive but I only managed to get a lot of values that I already have.
function map2ul($file_map,$html="") {
var_dump($file_map);
print "<br>";
if ($html == "") $html = '<ul>';
else $html .= '<ul>';
foreach ($file_map as $df) :
if (is_array($df)) :
$html .= $this->map2ul($df,$html);
else :
$html .= '<li>';
$html .= $df;
$html .= '</li>';
endif;
endforeach;
$html .= '</ul>';
return $html;
}
This is what I have tried but it seems that the foreach statement is recurred more times than it's needed.
Can someone please point me the error so I can understand better how to recurse this?
Upvotes: 0
Views: 304
Reputation: 3748
The error is in this lines:
if ($html == "") $html = '<ul>';
else $html .= '<ul>';
When you try to call this function recursively, the non-empty $html
is passed recursively causing the interior loop to glue sub-folder contents. @AgreeOrNot has already pointed one solution. The other is not to pass $html
to the recursively called function:
$html .= $this->map2ul($df);
But I think that your approach introduces some unnecessary logic and processing.
By analyzing the array we can draw one important conclusion: if the array value is an array, the corresponding key is folder name. In other case the value is file name:
function map2ul($file_map) {
$html = '<ul>';
foreach ($file_map as $file_id_or_folder_name => $file_name_or_folder_content) {
// if the element is a file
if ( ! is_array($file_name_or_folder_content)) {
$html .= '<li>' . $file_name_or_folder_content . '</li>';
} else { // if the element is a folder
$html .= '<li>/ ' . $file_id_or_folder_name . '</li>';
}
}
$html .= '</ul>';
return $html;
}
Now it's enough to inject sub-folders contents where it's necessary, i.e. for folders:
function map2ul($file_map) {
$html = '<ul>';
foreach ($file_map as $file_id_or_folder_name => $file_name_or_folder_content) {
// if the element is a file
if ( ! is_array($file_name_or_folder_content)) {
$html .= '<li>' . $file_name_or_folder_content . '</li>';
} else { // if the element is a folder
$html .= '<li>/ ' . $file_id_or_folder_name . '</li>';
// injecting sub-folder's contents
$html .= map2ul($file_name_or_folder_content);
}
}
$html .= '</ul>';
return $html;
}
if I want for this piece of code
$html .= '<li>' . $file_name_or_folder_content . '</li>';
to append the data-filepath attribute, which will be the parent_folder/file_name path, what do I need to do?
You have to pass the full path to the function. And the full path needs to be constructed at the function call:
function map2ul($file_map, $path = '') {
$path = $path . '/';
$html = '<ul>';
foreach ($file_map as $file_id_or_folder_name => $file_name_or_folder_content) {
// if the element is a file
if ( ! is_array($file_name_or_folder_content)) {
$html .= '<li data-filepath="' . $path . $file_name_or_folder_content . '">' . $file_name_or_folder_content . '</li>';
} else { // if the element is a folder
$html .= '<li>/ ' . $file_id_or_folder_name . '</li>';
$html .= map2ul($file_name_or_folder_content, $path . $file_id_or_folder_name);
}
}
$html .= '</ul>';
return $html;
}
Try without second parameter, e.g map2ul($file_map)
and with second parameter, e.g map2ul($file_map, 'c:/my_files')
.
Upvotes: 2
Reputation: 799
$html .= $this->map2ul($df,$html);
It shouldn't be a concatenation, because the recursive call is based on the parameter $html
- that is, the concatenation is already done in the recursive call. Change it to:
$html = $this->map2ul($df,$html);
Upvotes: 2