Nasuh Nasuh - 2 months ago 12
PHP Question

find biggest numbered folder in subdirectories and serve it with json

I have folder structure like below:

-Manga
-Berserk
-345
-346
-One Piece
-840
-841


And want JSON output like below:

{"0" => ["name":"Berserk", "last":"346"],
"1" => ["name":"One Piece, "last":"841"]}


Like the title says I want JSON output that gives me every series name in manga folder and biggest numbered folder that belongs to that series.

I have something like this at the moment.

<?php
$path = dirname(__FILE__) . "/../../manga";
$dir = new DirectoryIterator($path);

$data = array("mangas"=> array());

foreach ($dir as $fileinfo) {
if (!$fileinfo->isDot() && $fileinfo->getFilename() !== ".DS_Store") {
array_push($data["mangas"], $fileinfo->getFilename());
}
}

header('Content-Type: application/json; charset=UTF-8');
echo json_encode($data);
?>


Edit: Slim Framework API

$app->get('/ana', function ($request, $response, $args) {

$path = "../../manga";
function getAll($path)
{
$dirs = [];
foreach (new DirectoryIterator($path) as $item) {
if (!$item->isDir() || $item->isDot()) {
continue;
}
if ($max = getMaxInDir($item->getRealPath())) {
$dirs[] = [
'name' => $item->getFilename(),
'last' => $max,
];
}
}
return $dirs;
}

function getMaxInDir($path)
{
$max = 0;
foreach (new DirectoryIterator($path) as $item) {
$name = $item->getFilename();
if (!$item->isDir() || $item->isDot() || !is_numeric($name)) {
continue;
}
if ($current = (int)$name > $max) {
$max = $current;
};
}

return $max;
}
return $this->response->withJson(getAll($path));
});


Output of
http://127.0.0.1/api/public/ana


[{"name":"Berserk","last":true},{"name":"One Piece","last":true}]

Answer

First of all your desired output is not a valid JSON. It should rather be

[
    {"name":"Berserk","last":346},
    {"name":"One Piece","last":841}
]

Now one way to do it

echo json_encode(getAll($path));

function getAll($path)
{
    $dirs = [];
    foreach (new DirectoryIterator($path) as $item) {
        if (!$item->isDir() || $item->isDot()) {
            continue;
        }
        if ($max = getMaxInDir($item->getRealPath())) {
            $dirs[] = [
                'name' => $item->getFilename(),
                'last' => $max,
            ];
        }
    }
    return $dirs;
}

function getMaxInDir($path)
{
    $max = 0;
    foreach (new DirectoryIterator($path) as $item) {
        $name = $item->getFilename();
        if (!$item->isDir() || $item->isDot() || !is_numeric($name)) {
            continue;
        }
        if ($current = (int)$name > $max) {
            $max = $current;
        };
    }

    return $max;
}