3

I have a site currently to display all directories and subdirectories (on MAC os) So I have the code here

$Directory = new RecursiveDirectoryIterator('/');
$Iterator = new RecursiveIteratorIterator($Directory);

foreach($Iterator as $name => $object){
   echo "$name<br/>";
}

so it will echo out all of the real path of the directory (currently working on windows environment)

C:\xampp\apache\bin
C:\xampp\apache\bin\.
C:\xampp\apache\bin\..
C:\xampp\apache\bin\ab.exe
C:\xampp\apache\bin\abs.exe
C:\myfolder\mysubfolder
C:\myfolder\mysubfolder\.
C:\myfolder\mysubfolder\..
C:\myfolder\mysubfolder\anotherfile.php
C:\myfolder\mysubfolder\another_folder
C:\myfolder\mysubfolder\another_folder\.
C:\myfolder\mysubfolder\another_folder\..
C:\myfolder\mysubfolder\another_folder\file.txt

What I want to do is, to display in list so something like:

C:\
    xampp\
       apache\
           bin\
               ab.exe
               abs.exe
    myfolder\
       mysubfolder\
           anotherfile.php\
           another_folder\
              file.txt

Is it possible to format the data in array like the one I put above, not the full path? I am not sure how to use 'explode' and to group them into new array...?

HI again, I tried these code:

foreach($objects as $name => $object){
$newname=explode('\\', $name);
 print_r($newname);
}

and it's giving me:

array = { [0] => C:\
[1]=>xampp
[2]=>apache
[3]=>bin}

array = { [0] => C:\ 
[1]=>xampp
[2]=>apache
[3]=>bin 
[4]-> . }

 array = { [0] => C:\ 
[1]=>xampp
[2]=>apache
[3]=>bin 
[4]=>.
[5]=>. . }

    array = { [0] => C:\ 
[1]=>xampp
[2]=>apache
[3]=>bin 
[4]=>ab.exe }

 array = { [0] => C:\ 
[1]=>xampp
[2]=>apache
[3]=>bin 
[4]=>abs.exe }

Now, I'm not sure how to loop them so they will echo in group e.g

xampp
  apache
     bin
        ab.exe
        abs.exe

thanks

1
  • Since the RecursiveIteratorIterator iterates over the tree as if it's flat, sparing you the information of the depth, it's probably the wrong tool here. You want to manually recursively iterate and keep track of the depth. Commented Mar 13, 2014 at 11:25

2 Answers 2

3

DirectoryIterator (+ Recursive Function) can do that for you.

$resutl = RecursiveDirectoryIterator(new DirectoryIterator('/path/to/dir'));

function RecursiveDirectoryIterator(DirectoryIterator $path)
{
    $data = array();
    foreach ($path as $node){
        if ($node->isDir() && !$node->isDot()){
            $data[$node->getFilename()] = RecursiveDirectoryIterator(new DirectoryIterator($node->getPathname()));
        }
        elseif ($node->isFile()){
            $data[] = $node->getFilename();
        }
    }
    return $data;
}
Sign up to request clarification or add additional context in comments.

4 Comments

Hi, thanks for your reply. I tried your code, the path I used is "." it will return filename that is on the same level as this php file containing this code. but I want to display the filename from the root. SO I changed the path to "/", it returns empty array...
@user2960754 php cannot access "/" by default, you have to add this path to open_basedir config if you want but i don't recommend that.
hi @Danial so how should I put the path? I need to iterate them from the root parent node (e.g C:\ )
@user2960754 add "/" or "c:\" to open_basedir if you have to.
0

Here is non-recursive version, which works by first sorting the iterated result, then by splitting the amount of paths.

<?
$folder = ".";
$Directory = new RecursiveDirectoryIterator($base);
$Iterator = new RecursiveIteratorIterator($Directory);
$SortedIterator = new SortedIterator($Iterator);

foreach($SortedIterator as $name){
    //   echo $name."\n";
   $path = explode(DIRECTORY_SEPARATOR, $name);
   $file = array_pop($path);
   // it's a directory
   if ($file == ".")
   {
      $file = array_pop($path) . DIRECTORY_SEPARATOR;
   }
   if ($file === "..")
   {
     continue;
   }

   $pathcount = count($path);
   echo str_repeat("    ", $pathcount).$file."\n";
}

# Taken from example: http://stackoverflow.com/questions/2930405/sort-directory-listing-using-recursivedirectoryiterator
class SortedIterator extends SplHeap
{
    public function __construct(Iterator $iterator)
    {
        foreach ($iterator as $item) {
            $this->insert($item);
        }
    }
    public function compare($b,$a)
    {
        return strcmp($a->getRealpath(), $b->getRealpath());
    }
}

Example output:

./
    ChangeLog
    LICENSE.BSD
    README.md
    bin/
        phantomjs
    example.txt
    examples/
        arguments.coffee
        arguments.js
        child_process-examples.coffee
        child_process-examples.js
        colorwheel.coffee
        colorwheel.js
        colorwheel.png
        countdown.coffee
        countdown.js
        detectsniff.coffee
        detectsniff.js
        direction.coffee
        direction.js
        echoToFile.coffee
        echoToFile.js
    rasterize.js
    third-party.txt

1 Comment

hi, thanks for your reply. I tried your code. but it doesn't display as your posted output,,,in my case, it echo out all the files and sub-files but they are on the same level...

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.