PHP - создать объект JSON с несколькими массивами - PullRequest
0 голосов
/ 23 апреля 2020

У меня есть функция PHP для создания дерева каталогов, и я не могу отформатировать результат, чтобы получить файл JSON, например:

[
  {
    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/',
      }
    ]
  }
]

Здесь моя функция PHP, кто-то может помочь меня? Спасибо

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);

Ответы [ 3 ]

2 голосов
/ 23 апреля 2020

^ что сказали эти ребята.

<?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);
1 голос
/ 23 апреля 2020

Как упомянуто в ответе ранее, вы json кодируете результат каждого возвращаемого значения scandir_rec, а окончательная закодированная строка заканчивается довольно грязно.

Другой нежелательный результат возникает из-за строки $data[] = ['nodes' => scandir_rec($path)];. В результате получается структура данных, которая не похожа на структуру файла JSON, который вы представили, но вместо этого рассматривает весь результат как массив, а не как объект. Я полагаю, что вы можете подумать о том, чтобы сделать что-то вроде этого:

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;
}

, что приведет к соответствующей структуре вашего примера.

Редактировать:

Чтобы получить результат, который затем вы можете сделать что-то вроде:

$directory = __DIR__;
$result = scandir_rec($directory);
$data = json_encode($data);
1 голос
/ 23 апреля 2020

Основная проблема заключается в том, что после каждого рекурсивного вызова вы возвращаете вложенные данные в виде строки, закодированной в json, а не в иерархию данных. Вы можете изменить это, чтобы вернуть данные, и вызывающему абоненту придется json кодировать результат.

В качестве альтернативы, когда вы делаете рекурсивный вызов, json_decode() возвращаемое значение. Поэтому измените строку ...

$data[] = ['nodes' => scandir_rec($path)]; 

на

$data[] = ['nodes' => json_decode(scandir_rec($path), true)];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...