55

I need to create a loop through all files in subdirectories. Can you please help me struct my code like this:

$main = "MainDirectory";
loop through sub-directories {
    loop through filels in each sub-directory {
        do something with each file
    }
};
2
  • what would you like to do with the files after looping through them? Commented Jan 6, 2010 at 16:38
  • 3
    This will help you, read the user contributed notes php.net/manual/en/function.scandir.php Commented Mar 18, 2013 at 9:34

9 Answers 9

160

Use RecursiveDirectoryIterator in conjunction with RecursiveIteratorIterator.

$di = new RecursiveDirectoryIterator('path/to/directory');
foreach (new RecursiveIteratorIterator($di) as $filename => $file) {
    echo $filename . ' - ' . $file->getSize() . ' bytes <br/>';
}
Sign up to request clarification or add additional context in comments.

2 Comments

In case it's of use to anyone, $file in the above is an instance of SplFileInfo, with the methods that go along with that (getBasename, getSize, etc) - took me a little while to figure that out.
@NickF yeah that is good to know! $file->isDir, $file->isDot are also very usefull.
9

You need to add the path to your recursive call.

function readDirs($path){
  $dirHandle = opendir($path);
  while($item = readdir($dirHandle)) {
    $newPath = $path."/".$item;
    if(is_dir($newPath) && $item != '.' && $item != '..') {
       echo "Found Folder $newPath<br>";
       readDirs($newPath);
    }
    else{
      echo '&nbsp;&nbsp;Found File or .-dir '.$item.'<br>';
    }
  }
}

$path =  "/";
echo "$path<br>";

readDirs($path);

Comments

9

You probably want to use a recursive function for this, in case your sub directories have sub-sub directories

$main = "MainDirectory";

function readDirs($main){
  $dirHandle = opendir($main);
  while($file = readdir($dirHandle)){
    if(is_dir($main . $file) && $file != '.' && $file != '..'){
       readDirs($file);
    }
    else{
      //do stuff
    }
  } 
}

didn't test the code, but this should be close to what you want.

7 Comments

It will fall in infinite loop trying to recursively read directory "." (single dot - current directory). You need to modify your if-statement: if (is_dir($file) and $file != '.')
thanks, I forgot about that, added it to the code. Glad I put that untested disclaimer :)
missing closing parenthesis while($file = readdir($dirHandle){, otherwise works perfect! Thanks.
This approach makes it hard in cases where you need the file path as well as the filename
I have a few improvement suggestions for your answer. Alas, the edit of the post was rejected, so I just post the link here: stackoverflow.com/review/suggested-edits/6260147
|
5

I like glob with it's wildcards :

foreach (glob("*/*.txt") as $filename) {
    echo "$filename\n";
}

Details and more complex scenarios.

But if You have a complex folders structure RecursiveDirectoryIterator is definitively the solution.

2 Comments

short'n'sweet. recommend replacing "\n" (linefeed when writing to a txt file) with "<br/>" (HTML line break).
Good idea about the wildcard! Didn't think of that.
4

Come on, first try it yourself!

What you'll need:

scandir()
is_dir()

and of course foreach

http://php.net/manual/en/function.is-dir.php

http://php.net/manual/en/function.scandir.php

2 Comments

If you're going to link to the Deutsch version of the docs at least answer the question in Deutsch.
@erier My bad, fixed the links.
3

Another solution to read with sub-directories and sub-files (set correct foldername):

<?php
$path = realpath('samplefolder/yorfolder');
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename)
{
        echo "$filename <br/>";
}
?>

Comments

2

Minor modification on what John Marty posted, if we can safely eliminate any items that are named . or ..

function readDirs($path){
  $dirHandle = opendir($path);
  while($item = readdir($dirHandle)) {
    $newPath = $path."/".$item;
    if (($item == '.') || ($item == '..')) {
        continue;
    }
    if (is_dir($newPath)) {
        pretty_echo('Found Folder '.$newPath);
        readDirs($newPath);
    } else {
        pretty_echo('Found File: '.$item);
    }
  }
}

function pretty_echo($text = '')
{
    echo $text;
    if (PHP_OS == 'Linux') {
        echo "\r\n";
    }
    else {
        echo "</br>";
    }
}

Comments

1
    <?php
    ini_set('max_execution_time', 300);  // increase the execution time of the file (in     case the number of files or file size is more).
    class renameNewFile {

    static function copyToNewFolder() {  // copies the file from one location to another.
        $main = 'C:\xampp\htdocs\practice\demo';  // Source folder (inside this folder subfolders and inside each subfolder files are present.)
        $main1 = 'C:\xampp\htdocs\practice\demomainfolder'; // Destination Folder
        $dirHandle = opendir($main); // Open the source folder
        while ($file = readdir($dirHandle)) { // Read what's there inside the source folder
            if (basename($file) != '.' && basename($file) != '..') {   // Ignore if the folder name is '.' or '..' 
                $folderhandle = opendir($main . '\\' . $file);   // Open the Sub Folders inside the Main Folder
                while ($text = readdir($folderhandle)) {
                    if (basename($text) != '.' && basename($text) != '..') {     //  Ignore if the folder name is '.' or '..'
                        $filepath = $main . '\\' . $file . '\\' . $text;
                        if (!copy($filepath, $main1 . '\\' . $text))           // Copy the files present inside the subfolders to destination folder
                            echo "Copy failed";
                        else {
                            $fh = fopen($main1 . '\\' . 'log.txt', 'a');     // Write a log file to show the details of files copied.
                            $text1 = str_replace(' ', '_', $text);
                            $data = $file . ',' . strtolower($text1) . "\r\n";
                            fwrite($fh, $data);
                            echo $text . " is copied <br>";
                        }
                    }
                }
            }
        }
    }

    static function renameNewFileInFolder() {                //Renames the files into desired name
        $main1 = 'C:\xampp\htdocs\practice\demomainfolder';
        $dirHandle = opendir($main1);

        while ($file = readdir($dirHandle)) {
            if (basename($file) != '.' && basename($file) != '..') {
                $filepath = $main1 . '\\' . $file;
                $text1 = strtolower($filepath);
                rename($filepath, $text1);
                $text2 = str_replace(' ', '_', $text1);
                if (rename($filepath, $text2))
                    echo $filepath . " is renamed to " . $text2 . '<br/>';
            }
        }
    }

}
        renameNewFile::copyToNewFolder();
        renameNewFile::renameNewFileInFolder();
?>

Comments

1
$allFiles = [];
public function dirIterator($dirName)
{
    $whatsInsideDir = scandir($dirName);
    foreach ($whatsInsideDir as $fileOrDir) {
        if (is_dir($fileOrDir)) {
            dirIterator($fileOrDir);
        }
        $allFiles.push($fileOrDir);
    }

    return $allFiles;
}

Comments

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.