PHP scandir recursively

GRX picture GRX · Dec 9, 2015 · Viewed 23.4k times · Source

I'd like my script to scandir recursively,

$files = scandir('/dir');
foreach($files as $file){
if(is_dir($file)){
    echo '<li><label class="tree-toggler nav-header"><i class="fa fa-folder-o"></i>'.$file.'</label>';
    $subfiles = scandir($rooturl.'/'.$file);
        foreach($subfiles as $subfile){
            // and so on and on and on
        }
        echo '<li>';
    } else {
        echo $file.'<br />';
    }
}

I'd like to loop this in a way that for each dir found by scandir, it runs another scandir on the folders that have been found within that dir,

So dir 'A' contains dir 1/2/3, it should now scandir(1), scandir(2), scandir(3) and so on for each dir found.

How can I manage to implement this easily without copy pasting the code over and over in every foreach?

EDIT: Since the answers are nearly the very same as I already tried, I'll update the question a bit.

With this script I need to create a treeview list. With the current posted scripts the following get's echo'd happens:

/images/dir1/file1.png
/images/dir1/file2.png
/images/dir1/file3.png
/images/anotherfile.php
/data/uploads/avatar.jpg
/data/config.php
index.php

What I actually need is:

<li><label>images</label>
    <ul>
        <li><label>dir1</label>
            <ul>
                <li>file1.png</li>
                <li>file2.png</li>
                <li>file3.png</li>
            </ul>
        </li>
        <li>anotherfile.php</li>
    </ul>
</li>
<li><label>data</label>
    <ul>
        <li><label>uploads</label>
            <ul>
                <li>avatar.jpg</li>
            </ul>
        </li>
        <li>config.php</li>
    </ul>
</li>
<li>index.php</li>

And so on, Thank you for the already posted answers!

Answer

Allain Lalonde picture Allain Lalonde · Oct 11, 2017

I know this is an old question but I wrote a version of this that was more functional. It doesn't use global state and uses pure functions to figure things out:

function scanAllDir($dir) {
  $result = [];
  foreach(scandir($dir) as $filename) {
    if ($filename[0] === '.') continue;
    $filePath = $dir . '/' . $filename;
    if (is_dir($filePath)) {
      foreach (scanAllDir($filePath) as $childFilename) {
        $result[] = $filename . '/' . $childFilename;
      }
    } else {
      $result[] = $filename;
    }
  }
  return $result;
}