2012-06-02 4 views
2

У меня есть данные, содержащиеся в массиве, который, как это так,Динамическое создание многомерного массива из другого массива с помощью PHP?

$file['info']['files'] = array(
    [0] => array(
     'length' => (int), 
     'path' => array (
       [0] => 'file.txt', 
     ), 
    ), 
    [1] => array(
     'length' => (int), 
     'path' => array (
       [0] => 'directory one', 
       [1] => 'file2.txt', 
     ), 
    ), 
    [2] => array(
     'length' => (int), 
     'path' => array (
       [0] => 'directory one', 
       [1] => 'directory two', 
       [2] => 'file3.txt', 
     ), 
    ), 
); 

$file['info']['files'] массив может содержать любое количество элементов. В массиве path, содержащемся в каждом массиве $file['info']['files'], возникает проблема.

Он содержит информацию о структуре файла. Если существует только один элемент, то это файл. Если существует более одного элемента, каждый элемент, начиная с вершины, является родительской папкой следующего элемента, а последний элемент - это файл в последней папке. На примере выше будет файловая структура

FILE file1.txt 
FOLDER directory one 
    FILE file2.txt 
    FOLDER directory two 
      FILE {file3.txt} 

Я хотел бы, чтобы извлечь эти данные в собственную матричную структуру, которая должна быть следующей,

$sortedFiles = array(
    'file1.txt' => (int), 
    'directory one' => array(
     'file2.txt' => (int), 
     'directory two' => array(
       'file3.txt' => (int), 
     ), 
    ), 
); 

У меня есть этот код до сих пор,

foreach($file['info']['files'] as $file) { 
    // LENGTH AND PATH ARE SET 
    if(isset($file['length'], $file['path'])) { 
     // GET COUNT OF FILE PATH ARRAY 
     $count = count($file['path']); 
     // SINGLE FILE 
     if($count == 1) { 
      $sortedFiles[$file['path'][0]] = $file['length']; 
     // FILES IN DIRECTORY 
     } else { 
      // BUILD ARRAY STRUCTURE FOR DIRECTORIES 
     } 
    } 
} 

У меня возникли проблемы с добавлением каталогов в массив. Я мог бы сделать это вручную, и только каждый раз отправляйте столько каталогов каждый раз, проверяя, существует ли массив для каталога, и если он его не создает, и если он существует, то добавьте его. Я пробовал это с помощью кода ниже, но он имеет только один каталог в глубину (код пошел там, где он говорит // BUILD ARRAY STRUCTURE выше).

// FOLDER NOT SET 
if(!isset($files[$file['path'][0]])) { 
    $sortedFiles[$file['path'][0]] = array($file['path'][1] => $file['length'],); 
// FOLDER SET 
} else { 
    $sortedFiles[$file['path'][0]][$file['path'][1]] = $file['length']; 
} 

Как динамически создавать массивы для каждого каталога, который существует и добавить информацию, которая необходима с учетом того, что структура каталогов может быть любое количество уровней в глубину?

Спасибо, что нашли время, чтобы прочитать мой довольно длинный вопрос, и я ценю любую помощь, которую кто-либо мне дает.

+0

являются вы познакомились с рекурсией? – heximal

+0

@heximal Нет Я новичок в php – Griff

+0

таких проблем (когда вы не знаете, сколько уровней гнездования) решаются с помощью рекурсивных функций. recusrive - это функция, которая называет себя – heximal

ответ

3

Вам нужно будет позвонить вашу функцию рекурсивно, как показано в следующем примере:

function get_contents_dir($dir) 
{ 
    $names = array(); 

    if (is_dir($dir) && is_readable($dir)) 
    { 
      foreach (scandir($dir) as $file) 
      { 
        if (is_dir($dir."/".$file) && is_readable($dir."/".$file)) 
        { 
          $names[] = get_contents_dir($dir."/".$file); 
        } 

        if (is_file($dir."/".$file) && is_readable($dir."/".$file)) 
        { 
          $names[] = $dir."/".$file; 
        } 
      } 
    } 

    return $names; 
} 

Эта функция сначала открывает папку набор $dir и просматривает список файлов, добавляя каждый найденный файл в массив, который , после сканирования папки, return ed как возвращаемое значение функции.

Закрутка происходит, когда запись результата scandir() (список файлов и папок в папке) на самом деле является папкой. Если это произойдет, функция вызывается из ее внутренних элементов, рекурсивно (см. Строку $names[] = get_contents_dir($dir."/".$file);, вызывающую функцию из функции), и вложенная папка также будет проиндексирована. Промойте и повторите, пока все подпапки не индексируются.

Если вы вызываете функцию и пусть она выполняется, массив будет возвращен. Каждый ключ массива будет элементом. Если это файл, значение, связанное с ключом, - это имя файла, если оно было папкой, это будет другой массив, вложенный в предыдущий.

Вот пример свалка взят из возвращенного массива:

array (
    0 => './libmysqlclient.so.16.0.0', 
    1 => './libmysqlclient_r.so.16.0.0', 
    2 => 
    array (
    0 => './libs/libboost_thread-mt.a', 
    1 => './libs/libboost_thread-mt.so.1.38.0', 
    2 => './libs/libmysql.dll', 
    3 => './libs/libmysqlclient16_5.1.41-3ubuntu12_i386.deb', 
), 
    3 => 
    array (
    0 => './radio_sneaker/cl_auto.lua', 
    1 => './radio_sneaker/sh_auto.lua', 
    2 => './radio_sneaker/sh_coms.lua', 
    3 => './radio_sneaker/sh_info.lua', 
    4 => './radio_sneaker/sv_auto.lua', 
    5 => './radio_sneaker/sv_hooks.lua', 
), 
    4 => './sv_auto.lua', 
) 

Сравните этот вывод против команды tree побежал на одной и той же папке:

| libmysqlclient.so.16.0.0 
| libmysqlclient_r.so.16.0.0 
| sv_auto.lua 
| 
+---libs 
|  libboost_thread-mt.a 
|  libboost_thread-mt.so.1.38.0 
|  libmysql.dll 
|  libmysqlclient16_5.1.41-3ubuntu12_i386.deb 
|  
\---radio_sneaker 
     cl_auto.lua 
     sh_auto.lua 
     sh_coms.lua 
     sh_info.lua 
     sv_auto.lua 
     sv_hooks.lua 
+0

Это потрясающе! Благодаря :) – Griff

1

Почему вы не используете функцию join в php для слияния пути, чтобы проверить, существует ли она? Если это не так, перейдите на уровень проверки уровня, если папка существует, а затем она не создается и не перемещается дальше. Я хочу сказать, что создание такой динамической структуры, прежде всего, сложно и легко испортить. Почему бы вам не пойти легко?

1

Представьте, что у вас есть массив, представляющий структуру каталога, которая изначально пуста и будет заполняться по частям. Вам нужно отслеживать «текущий» элемент в этом массиве и перебирать имена каталогов. На каждой итерации вы создадите под-массив под текущим элементом, если он еще не существует, а затем установите текущий этот подматрица.

Это может быть сделано либо с рекурсией, либо с итерацией, а так как это PHP, «текущий» маркер должен быть ссылкой.

Имея этот обзор, взгляните на this question и ответы там. Вход есть в виде строки, но это всего лишь implode вдали от вашей текущей ситуации.

+0

Хорошо спасибо, я посмотрю – Griff

1

Я позволю вам бороться с этим в ваш код, но это важные уроки.

превратить плоский массив в вложенную структуру

$a = array(
    'dir1', 'dir2', 'file.txt' 
); 

$structure = array(array_pop($a)); 
foreach (array_reverse($a) as $dir) { 
    $structure = array($dir => $structure); 
} 

print_r($structure); 

объединить одну структуры в другую

$result = array_merge_recursive($result, $structure); 

Просто перебрать все структуры для сращивания.

+0

Благодарю вас, я попробую сейчас и посмотрю, смогу ли я заставить его работать :) – Griff

Смежные вопросы