Разобрать структуру каталогов (строки) в JSON с помощью PHP

У меня есть массив строк пути к файлу, подобных этому

  • видео/смешно/jelloman.wmv
  • видео/смешно/bellydance.flv
  • видео/abc.mp4
  • видео/июнь.mp4
  • видео/тесак.mp4
  • аудио/uptown.mp3
  • аудио/сочный.mp3
  • весело.wmv
  • Джимми.wmv
  • Герман.wmv

Конечная цель — получить их в jsTree. Я построил дерево прототипов из приведенных выше образцов строк. проверьте это: http://jsfiddle.net/ecropolis/pAqas/


person Ecropolis    schedule 13.02.2011    source источник
comment
Вы должны исправить форматирование... Вставьте весь код, затем используйте кнопку {}, чтобы сделать отступы правильными. (Или отступ все 4 пробела).   -  person Jacob    schedule 14.02.2011
comment
Я не вижу рекурсивности в вашей структуре...   -  person Felix Kling    schedule 14.02.2011
comment
Папка «Смешно» вложена в папку «Видео». Я только что вложил один уровень, но мог бы продолжить. Я никак не могу понять форматирование! Прости.   -  person Ecropolis    schedule 14.02.2011


Ответы (3)


Во-первых, я бы создал рекурсивную функцию для перебора вашего каталога в массив

function ReadFolderDirectory($dir,$listDir= array())
{
    $listDir = array();
    if($handler = opendir($dir))
    {
        while (($sub = readdir($handler)) !== FALSE)
        {
            if ($sub != "." && $sub != ".." && $sub != "Thumb.db")
            {
                if(is_file($dir."/".$sub))
                {
                    $listDir[] = $sub;
                }elseif(is_dir($dir."/".$sub))
                {
                    $listDir[$sub] = $this->ReadFolderDirectory($dir."/".$sub); 
                } 
            } 
        }    
        closedir($handler); 
    } 
    return $listDir;    
}

а затем выведите массив с помощью json_encode.

Источник использован из: http://www.php.net/manual/en/function.readdir.php#87733

person RobertPitt    schedule 13.02.2011
comment
У меня есть имена файлов выше как строки в массиве. Поскольку я не читаю настоящий каталог с PHP, у меня нет доступа к таким функциям, как is_file, возможно, это все, что мне действительно нужно. В моем случае, если я разделяю на «/», файл является последним элементом разнесенной строки в массив. (Строки файлов поступают из запроса к Amazon S3) - person Ecropolis; 14.02.2011
comment
@RobertPitt Пытается добиться аналогичного результата с помощью RecursiveIterator. Спасибо за любую помощь в stackoverflow.com/questions /24121723/ - person YahyaE; 10.06.2014
comment
Это выдает ошибку PHP Неустранимая ошибка: Uncaught Error: Использование $this, когда не в контексте объекта - person Ruvenss; 14.10.2020

Я смог использовать это отличное решение (нижнее, опубликованное @Casablanca) для обработки приведенных выше строк в структуру рекурсивного массива. Преобразовать массив путей в список UL

<?php
    $paths = array('videos/funny/jelloman.wmv','videos/funny/bellydance.flv','videos/abc.mp4','videos/june.mp4','videos/cleaver.mp4','audio/uptown.mp3','audio/juicy.mp3','fun.wmv', 'jimmy.wmv','herman.wmv');
    sort($paths); 
    $array = array();
    foreach ($paths as $path) {
      $path = trim($path, '/');
      $list = explode('/', $path);
      $n = count($list);

      $arrayRef = &$array; // start from the root
      for ($i = 0; $i < $n; $i++) {
        $key = $list[$i];
        $arrayRef = &$arrayRef[$key]; // index into the next level
      }
    }

    function buildUL($array, $prefix,$firstrun) {     
        $c = count($array);
      foreach ($array as $key => $value) {
            $path_parts = pathinfo($key);
            if($path_parts['extension'] != '') {
                $extension = $path_parts['extension'];
            } else {
                $extension = 'folder';
            }
            if ($prefix == '') { //its a folder
                echo ' { "data":"'.$key.'"';
            } else { //its a file
                echo '{"data" : {"title":"'.$key.'"},"attr":{"href": "'.$prefix.$key.'","id": "1239"},
                "icon": "images\/'.$extension.'-icon.gif"';
            }
            // if the value is another array, recursively build the list$key
            if (is_array($value)) {
                echo ',"children" : [ ';
                buildUL($value, "$prefix$key/",false);
            }
            echo "}";
            $c = $c-1;
            if($c != 0) {
                echo ",";
            }
      } //end foreach
     if($firstrun != true) 
      echo "]";
    }

    echo '{ "data" : [';
    buildUL($array, '',true);
    echo '] }';
?> 
person Ecropolis    schedule 17.02.2011
comment
Я проголосовал за то, что вы попытались вручную создать объект json, используя только конкатенацию, пожалуйста, обратитесь к сложности, которую на самом деле обеспечивает json_encode - person RobertPitt; 01.06.2011

Я исправил ответ конкатенации, выбранный @Ecropolis для использования массивов. Его первоначальный пример помог мне, но я согласен с @RobertPitt, что мне нужен json_encode, чтобы действительно быть хорошим решением.

  $filesArray = array('videos/funny/jelloman.wmv','videos/funny/bellydance.flv','videos/abc.mp4','videos/june.mp4','videos/cleaver.mp4','audio/uptown.mp3','audio/juicy.mp3','fun.wmv', 'jimmy.wmv','herman.wmv');
  $finalTree = $this->parseArrayToTree($filesArray);

  $finalJsonTree = json_encode($finalTree);

  function parseArrayToTree($paths) {
    sort($paths);
    $array = array();
    foreach ($paths as $path)
    {
      $path = trim($path, '/');
      $list = explode('/', $path);
      $n = count($list);

      $arrayRef = &$array; // start from the root
      for ($i = 0; $i < $n; $i++)
      {
        $key = $list[$i];
        $arrayRef = &$arrayRef[$key]; // index into the next level
      }
    }

    $dataArray = array();
    $dataArray['data'] = array();
    $dataArray['data'] = $this->buildUL($array, '');
    return $dataArray;
  }

  function buildUL($array, $prefix) {
    $finalArray = array();

    foreach ($array as $key => $value)
    {
      $levelArray = array();
      $path_parts = pathinfo($key);
      if (!empty($path_parts['extension']) && $path_parts['extension'] != '')
      {
        $extension = $path_parts['extension'];
      }
      else
      {
        if (empty($value))
        {
          $extension = "";
        }
        else if (is_array($value))
        {
          $extension = 'folder';
        }
      }

      if (is_array($value))
      { //its a folder
        $levelArray['data'] = $key;
      }
      else
      { //its a file
        $levelArray['data']['title'] = $key;
        $levelArray['attr']['href'] = $prefix . $key;
        $levelArray['attr']['id'] = $prefix . $key;
        $levelArray['icon'] = "images/" . $extension . "-icon.gif";
      }

      // if the value is another array, recursively build the list$key
      if (is_array($value))
      {
        $levelArray['children'] = $this->buildUL($value, $prefix . $key . "/");
      }

      $finalArray[] = $levelArray;
    } //end foreach

    return $finalArray;
  }
person janson0    schedule 12.07.2013