7

I want to create a file tree, and for this purpose I need to convert an array of files and directories to a multidimensional file tree array. For example:

array
(
   'file.txt',
   'dir1/',
   'dir1/dir2/',
   'dir1/dir2/dir3/',
   'dir1/file.txt',
)

to

array
(
   'file.txt',
   'dir1' => 
   array
   (
       'dir2' => 
       array
       (
           'dir3' =>
           array(),
       ),
       'file.txt',
    )
)

I've tried several functions to accomplish this, but non of them worked. The problem I've encountered for example that there is no easy way to convert an array ('test','test','test'),'test' to $array['test']['test']['test'] = 'test'.

0

3 Answers 3

6

Here's a shorter recursive one:

function dir_tree($dir) {    
    $files = array_map('basename', glob("$dir/*"));
    foreach($files as $file) {
        if(is_dir("$dir/$file")) {
            $return[$file] = dir_tree("$dir/$file");
        } else {
            $return[] = $file;
        }
    }
    return $return;
}
1
  • Been looking for something like this. I'm glad I saw this one before I reinvented the wheel. Commented Apr 20, 2017 at 17:11
4

Take a look to my post here.

The answer is: strtok will save you.

<?php

$input = [
'/RootFolder/Folder1/File1.doc',
'/RootFolder/Folder1/SubFolder1/File1.txt',
'/RootFolder/Folder1/SubFolder1/File2.txt',
'/RootFolder/Folder2/SubFolder1/File2.txt',
'/RootFolder/Folder2/SubFolder1/SubSubFolder1/File4.doc',
];

function parseInput($input) {
  $result = array();

  foreach ($input AS $path) {
  $prev = &$result;

  $s = strtok($path, '/');

  while (($next = strtok('/')) !== false) {
    if (!isset($prev[$s])) {
      $prev[$s] = array();
    }

  $prev = &$prev[$s];
  $s = $next;
  }
$prev[] = $s;

unset($prev);
}
return $result;
}

var_dump(parseInput($input));

Output :

array(1) {
  ["RootFolder"]=>
  array(2) {
    ["Folder1"]=>
     array(2) {
       [0]=>
       string(9) "File1.doc"
       ["SubFolder1"]=>
       array(2) {
         [0]=>
    string(9) "File1.txt"
         [1]=>
         string(9) "File2.txt"
       }
     }
     ["Folder2"]=>
     array(1) {
       ["SubFolder1"]=>
       array(2) {
         [0]=>
         string(9) "File2.txt"
         ["SubSubFolder1"]=>
         array(1) {
           [0]=>
           string(9) "File4.doc"
         }
       }
     }
   }
 }
1
  • Perfect, been racking my brain all day and this is it! Super! Commented Jul 11, 2019 at 9:44
1

I have PHP snippet for that:

<?php
function wps_glob($dir) {
  foreach (glob($dir . '/*') as $f) {
    if(is_dir($f)) {
      $r[] = array(basename($f) => wps_glob($f));
    }
    else {
      $r[] = basename($f);
    }
  }
  return $r;
}

function wps_files($path) {
  $wpsdir = Array(
     'root' => $path,
     'struktur' =>  wps_glob($path)
  );
  return $wpsdir;
}
?>

example usage here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.