Reputation: 1
I have a PHP function to create a directory tree and I cannot format the result to obtain a JSON file like this:
[
{
text: 'Parent',
href: 'parent/',
nodes: [
{
text: 'Child',
href: 'child/',
nodes: [
{
text: 'Grandchild',
href: 'grandchild/',
},
{
text: 'Grandchild',
href: 'grandchild/',
}
]
},
{
text: 'Child',
href: 'child/',
}
]
},
{
text: 'Parent',
href: 'parent/',
},
{
text: 'Parent',
href: 'parent/',
},
{
text: 'Parent',
href: 'parent/',
},
{
text: 'Parent',
href: 'parent/',
},
{
text: 'Parent',
href: 'parent/',
nodes: [
{
text: 'Child',
href: 'child/',
nodes: [
{
text: 'Grandchild',
href: 'grandchild/',
},
{
text: 'Grandchild',
href: 'grandchild/',
}
]
},
{
text: 'Child',
href: 'child/',
}
]
}
]
Here my PHP function, someone can help me? Thanks
function scandir_rec($root)
{
$data = [];
if (!is_dir($root)) {
return;
}
$dirs = scandir($root);
foreach ($dirs as $dir) {
if ($dir == '.' || $dir == '..') {
continue;
}
$path = $root . '/' . $dir;
$data[] = ['text'=>$dir, 'link'=>urlencode($path)];
if (is_dir($path)) {
$data[] = ['nodes' => scandir_rec($path)];
}
}
return json_encode($data, JSON_UNESCAPED_SLASHES);
}
// init call
$rootDir = '/var/usr';
scandir_rec($rootDir);
Upvotes: 0
Views: 133
Reputation: 1160
^what those guys said.
<?php
function scandir_rec($root)
{
$data = [];
if (!is_dir($root)) {
return;
}
$dirs = scandir($root);
foreach ($dirs as $dir) {
if ($dir == '.' || $dir == '..') {
continue;
}
$path = $root . DIRECTORY_SEPARATOR . $dir;
if (!is_dir($path)) continue;
$chunk = ['text' => $dir, 'link' => urlencode($path)];
$nodes = scandir_rec($path);
if (!empty($nodes)) $chunk['nodes'] = $nodes;
$data[] = $chunk;
}
return $data;
}
$rootDir = '/var/usr';
json_encode(scandir_rec($rootDir), JSON_UNESCAPED_SLASHES);
Upvotes: 2
Reputation: 724
As mentioned in answer before, your are json encoding the result of each return value of scandir_rec
, with the final encoded string ending up quite messy.
Another undesirable result occurs because of the line $data[] = ['nodes' => scandir_rec($path)];
. Resulting in a data structure that does not resemble the structure of the JSON file you presented, but instead considers the entire result as an array instead of an object. I believe you might want to consider doing something like this:
function scandir_rec($root)
{
if (!is_dir($root)) {
return [];
}
$data = [];
$data['text'] = $root;
$data['href'] = urlencode($root);
$nodes = [];
$dirs = scandir($root);
foreach ($dirs as $dir) {
if ($dir === '.' || $dir === '..') {
continue;
}
$path = $root . '/' . $dir;
if (is_dir($path)) {
$nodes[] = scandir_rec($path);
}
}
if (false === empty($nodes)) {
$data['nodes'] = $nodes;
}
return $data;
}
Which results in a matching structure of your example.
Edit:
To get the result that you want, you could then do something like:
$directory = __DIR__;
$result = scandir_rec($directory);
$data = json_encode($data);
Upvotes: 1
Reputation: 57121
The main problem is that after each recursive call, you return the sub data as a json encoded string rather than the data hierarchy. You could change this to return the data and the caller would have to json encode the result.
Alternatively, when you do the recursive call, json_decode()
the return value. So change the line...
$data[] = ['nodes' => scandir_rec($path)];
to
$data[] = ['nodes' => json_decode(scandir_rec($path), true)];
Upvotes: 1