Listing all the folders subfolders and files in a directory using php

PhpDirectory

Php Problem Overview


Please give me a solution for listing all the folders,subfolders,files in a directory using php. My folder structure is like this:

Main Dir
 Dir1
  SubDir1
   File1
   File2
  SubDir2
   File3
   File4
 Dir2
  SubDir3
   File5
   File6
  SubDir4
   File7
   File8

I want to get the list of all the files inside each folder.

Is there any shell script command in php?

Php Solutions


Solution 1 - Php

function listFolderFiles($dir){
    $ffs = scandir($dir);

    unset($ffs[array_search('.', $ffs, true)]);
    unset($ffs[array_search('..', $ffs, true)]);

    // prevent empty ordered elements
    if (count($ffs) < 1)
        return;

    echo '<ol>';
    foreach($ffs as $ff){
        echo '<li>'.$ff;
        if(is_dir($dir.'/'.$ff)) listFolderFiles($dir.'/'.$ff);
        echo '</li>';
    }
    echo '</ol>';
}

listFolderFiles('Main Dir');

Solution 2 - Php

A very simple way to show folder structure makes use of RecursiveTreeIterator class (PHP 5 >= 5.3.0, PHP 7) and generates an ASCII graphic tree.

$it = new RecursiveTreeIterator(new RecursiveDirectoryIterator("/path/to/dir", RecursiveDirectoryIterator::SKIP_DOTS));
foreach($it as $path) {
  echo $path."<br>";
}

http://php.net/manual/en/class.recursivetreeiterator.php

There is also some control over the ASCII representation of the tree by changing the prefixes using RecursiveTreeIterator::setPrefixPart, for example $it->setPrefixPart(RecursiveTreeIterator::PREFIX_LEFT, "|");

Solution 3 - Php

This code lists all directories and files in sorted order in a tree view. It's a site map generator with hyper-links to all the site resources. The full web page source is here. You'll need to change the path on the ninth line from the end.

<?php
$pathLen = 0;

function prePad($level)
{
  $ss = "";
  
  for ($ii = 0;  $ii < $level;  $ii++)
  {
    $ss = $ss . "|&nbsp;&nbsp;";
  }
  
  return $ss;
}

function myScanDir($dir, $level, $rootLen)
{
  global $pathLen;
  
  if ($handle = opendir($dir)) {

    $allFiles = array();
    
    while (false !== ($entry = readdir($handle))) {
      if ($entry != "." && $entry != "..") {
        if (is_dir($dir . "/" . $entry))
        {
          $allFiles[] = "D: " . $dir . "/" . $entry;
        }
        else
        {
          $allFiles[] = "F: " . $dir . "/" . $entry;
        }
      }
    }
    closedir($handle);
  
    natsort($allFiles);
  
    foreach($allFiles as $value)
    {
      $displayName = substr($value, $rootLen + 4);
      $fileName    = substr($value, 3);
      $linkName    = str_replace(" ", "%20", substr($value, $pathLen + 3));
      if (is_dir($fileName)) {
        echo prePad($level) . $linkName . "<br>\n";
        myScanDir($fileName, $level + 1, strlen($fileName));
      } else {
        echo prePad($level) . "<a href=\"" . $linkName . "\" style=\"text-decoration:none;\">" . $displayName . "</a><br>\n";
      }
    }
  }
}

?><!DOCTYPE HTML>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Site Map</title>
</head>

<body>
<h1>Site Map</h1>
<p style="font-family:'Courier New', Courier, monospace; font-size:small;">
<?php
  $root = '/home/someuser/www/website.com/public';
  
  $pathLen = strlen($root);
  
  myScanDir($root, 0, strlen($root)); ?>
</p>
</body>

</html>

Solution 4 - Php

In case you want to use directoryIterator

Following function is a re-implementation of @Shef answer with directoryIterator

function listFolderFiles($dir)
{
    echo '<ol>';
    foreach (new DirectoryIterator($dir) as $fileInfo) {
        if (!$fileInfo->isDot()) {
            echo '<li>' . $fileInfo->getFilename();
            if ($fileInfo->isDir()) {
                listFolderFiles($fileInfo->getPathname());
            }
            echo '</li>';
        }
    }
    echo '</ol>';
}
listFolderFiles('Main Dir');

Solution 5 - Php

I'm really fond of SPL Library, they offer iterator's, including RecursiveDirectoryIterator.

Solution 6 - Php

If you're looking for a recursive directory listing solutions and arrange them in a multidimensional array. Use below code:

<?php
/**
 * Function for recursive directory file list search as an array.
 *
 * @param mixed $dir Main Directory Path.
 *
 * @return array
 */
function listFolderFiles($dir)
{
    $fileInfo     = scandir($dir);
    $allFileLists = [];

    foreach ($fileInfo as $folder) {
        if ($folder !== '.' && $folder !== '..') {
            if (is_dir($dir . DIRECTORY_SEPARATOR . $folder) === true) {
                $allFileLists[$folder] = listFolderFiles($dir . DIRECTORY_SEPARATOR . $folder);
            } else {
                $allFileLists[$folder] = $folder;
            }
        }
    }

    return $allFileLists;
}//end listFolderFiles()


$dir = listFolderFiles('your searching directory path ex:-F:\xampp\htdocs\abc');
echo '<pre>';
print_r($dir);
echo '</pre>'

?>

Solution 7 - Php

Have a look at glob() or the recursive directory iterator.

Solution 8 - Php

Solution 9 - Php

It will use to make menu bar in directory format

$pathLen = 0;

function prePad($level)
{
  $ss = "";

  for ($ii = 0;  $ii < $level;  $ii++)
  {
      $ss = $ss . "|&nbsp;&nbsp;";
    }

    return $ss;
  }

  function myScanDir($dir, $level, $rootLen)
  {
    global $pathLen;

    if ($handle = opendir($dir)) {

      $allFiles = array();

      while (false !== ($entry = readdir($handle))) {
        if ($entry != "." && $entry != "..") {
          if (is_dir($dir . "/" . $entry))
          {
            $allFiles[] = "D: " . $dir . "/" . $entry;
          }
          else
          {
            $allFiles[] = "F: " . $dir . "/" . $entry;
          }
        }
      }
      closedir($handle);

      natsort($allFiles);

      foreach($allFiles as $value)
      {
        $displayName = substr($value, $rootLen + 4);
        $fileName    = substr($value, 3);
        $linkName    = str_replace(" ", " ", substr($value, $pathLen + 3));
  
  
        if (is_dir($fileName))
         {
		       echo "<li ><a class='dropdown'><span>" . $displayName . "                    </span></a><ul>";
		 
   		  myScanDir($fileName, $level + 1, strlen($fileName));
   		  	echo "</ul></li>";
  } 
        else {
      $newstring = substr($displayName, -3);  
      if($newstring == "PDF" || $newstring == "pdf" )

          echo "<li ><a href=\"" . $linkName . "\" style=\"text-decoration:none;\">" . $displayName . "</a></li>";
 	
        }
  $t;
        if($level != 0)
        {
  	      if($level < $t)
  	      {
		$r = int($t) - int($level);
		for($i=0;$i<$r;$i++)
		{
			echo "</ul></li>";
		}
	      }	
        }
              $t = $level;
      }
          }

        }
        ?>
   
										<li style="color: #ffffff">
											
												<?php													
   //  ListFolder('D:\PDF');
     $root = 'D:\PDF';
   $pathLen = strlen($root);

    myScanDir($root, 0, strlen($root)); 
     ?>
												 
												
										</li>

Solution 10 - Php

I was looking for a similar function to this. I needed directories as keys and subdirectories as arrays and files to just be placed as values.
I used the following code:

/**
 * Return an array of files found within a specified directory.
 * @param  string $dir   A valid directory. If a path, with a file at the end,
 *                       is passed, then the file is trimmed from the directory.
 * @param  string $regex Optional. If passed, all file names will be checked
 *                       against the expression, and only those that match will
 *                       be returned.
 *                       A RegEx can be just a string, where a '/' will be
 *                       prefixed and a '/i' will be suffixed. Alternatively,
 *                       a string could be a valid RegEx string.
 * @return array         An array of all files from that directory. If regex is
 *                       set, then this will be an array of any matching files.
 */
function get_files_in_dir(string $dir, $regex = null)
{
    $dir = is_dir($dir) ? $dir : dirname($dir);
    // A RegEx to check whether a RegEx is a valid RegEx :D
    $pass = preg_match("/^([^\\\\a-z ]).+([^\\\\a-z ])[a-z]*$/i", $regex, $matches);

    // Any non-regex string will be caught here.
    if (isset($regex) && !$pass) {
        //$regex = '/'.addslashes($regex).'/i';
        $regex = "/$regex/i";
    }

    // A valid regex delimiter with different delimiters will be caught here.
    if (!empty($matches) && $matches[1] !== $matches[2]) {
        $regex .= $matches[1] . 'i'; // Append first delimiter and i flag
    }

    try {
        $files = scandir($dir);
    } catch (Exception $ex) {
        $files = ['.', '..'];
    }
    $files = array_slice($files, 2); // Remove '.' and '..'
    $files = array_reduce($files, function($carry, $item) use ($regex) {
        if ((!empty($regex) && preg_match($regex, $item)) || empty($regex)) {
            array_push($carry, $item);
        }

        return $carry;
    }, []);

    return $files;
}

function str_finish($value, $cap)
{
    $quoted = preg_quote($cap, '/');

    return preg_replace('/(?:'.$quoted.')+$/u', '', $value).$cap;
}

function get_directory_tree($dir)
{
    $fs = get_files_in_dir($dir);
    $files = array();

    foreach ($fs as $k => $f) {
        if (is_dir(str_finish($dir, '/').$f)) {
            $fs[$f] = get_directory_tree(str_finish($dir, '/').$f);
        } else {
            $files[] = $f;
        }
        unset($fs[$k]);

    }

    $fs = array_merge($fs, $files);

    return $fs;
}

There's a lot to take in.

The first function get_files_in_dir function was created so that I could get all files and folders in a directory based on a regular expression. I use it here because it has some error checking to make sure a directory is converted into an array.

Next, we have a simple function that just adds a forward slash to the end of a string if there isn't one there already.

Finally, we have the get_directory_tree function which will iterate through all the folders and sub folders and create an associative array where the folder names are the keys and files are the values (unless the folder has sub folders).

Solution 11 - Php

The precedents answers didn't meet my needs.

If you want all files and dirs in one flat array, you can use this function (found here) :

// Does not support flag GLOB_BRACE        
function glob_recursive($pattern, $flags = 0) {
    $files = glob($pattern, $flags);
    foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
        $files = array_merge($files, glob_recursive($dir.'/'.basename($pattern), $flags));
    }
    return $files;
}

In my case :

$paths = glob_recursive(os_path_join($base_path, $current_directory, "*"));

returns me an array like this :

['/home/dir','/home/dir/image.png','/home/dir/subdir','/home/dir/subdir/file.php',]
You can also use dynamic path generation :
$paths = glob_recursive(os_path_join($base_path, $directory, "*"));

With this function :

function os_path_join(...$parts) {
  return preg_replace('#'.DIRECTORY_SEPARATOR.'+#', DIRECTORY_SEPARATOR, implode(DIRECTORY_SEPARATOR, array_filter($parts)));
}
If you wan get only directories you can use :
$paths = glob_recursive(os_path_join($base_path, $current_directory, "*"));
$subdirs = array_filter($paths, function($path) {
    return is_dir($path);
});

Solution 12 - Php

Here is A simple function with scandir& array_filter that do the job. filter needed files using regex. I removed . .. and hidden files like .htaccess, you can also customise output using <ul> and colors and also customise errors in case no scan or empty dirs!.

function getAllContentOfLocation($loc)
{	
	$scandir = scandir($loc);

	$scandir = array_filter($scandir, function($element){

		return !preg_match('/^\./', $element);

	});

	if(empty($scandir)) echo '<li style="color:red">Empty Dir</li>';

	foreach($scandir as $file){

		$baseLink = $loc . DIRECTORY_SEPARATOR . $file;

		echo '<ol>';
		if(is_dir($baseLink))
		{
			echo '<li style="font-weight:bold;color:blue">'.$file.'</li>';
			getAllContentOfLocation($baseLink);

		}else{
			echo '<li>'.$file.'</li>';
		}
		echo '</ol>';
	}
}
//Call function and set location that you want to scan 
getAllContentOfLocation('../app');

Solution 13 - Php

This is my handy method PHP 7 style:

  /**
     * @param string $directory
     *
     * @return SplFileInfo[]
     */
    private function getAllFiles(string $directory = './'): array
    {
        $result = [];

        $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory), RecursiveIteratorIterator::SELF_FIRST );
        /** @var $fileInfo SplFileInfo */
        foreach ($iterator as $fileInfo ) {

            if ($fileInfo->isFile()) {
               $result[] = $fileInfo;
            }
        }

        return $result;
    }

Solution 14 - Php

Here's another recursive scandir() as a generator. The generator yields full paths (in the form "basedir/subdirs.../file") so it is less suitable for a tree display and more appropriate for directory scanning where you want to do something else with the file paths - such as display an image gallery.

function listFolderFiles($dir){
	foreach(scandir($dir) as $file){
		if ($file[0] == '.')
			continue;
		if (is_dir("$dir/$file"))
			foreach (listFolderFiles("$dir/$file") as $infile)
				yield $infile;
		else
			yield "${dir}/${file}";
	}
}

This implementation skips the directory pointers by skipping all UNIX hidden files (files that start with a period) - if you want to get "hidden" files, then you need to change the directory pointer skipping method to something else.

You can use it like this:

<?php foreach (listFolderFiles('.') as $file) {
	?>
	<?php echo $file?><br/>
	<?php
}?>

Solution 15 - Php

You can also try this:

<?php
function listdirs($dir) {
    static $alldirs = array();
    $dirs = glob($dir . '/*', GLOB_ONLYDIR);
    if (count($dirs) > 0) {
        foreach ($dirs as $d) $alldirs[] = $d;
    }
    foreach ($dirs as $dir) listdirs($dir);
    return $alldirs;
}

$directory_list = listdirs('xampp');
print_r($directory_list);
?>

Solution 16 - Php

define ('PATH', $_SERVER['DOCUMENT_ROOT'] . dirname($_SERVER['PHP_SELF']));
$dir = new DirectoryIterator(PATH);
echo '<ul>';
foreach ($dir as $fileinfo)
{	
    if (!$fileinfo->isDot()) {
       echo '<li><a href="'.$fileinfo->getFilename().'" target="_blank">'.$fileinfo->getFilename().'</a></li>'; 
	  
	   echo '</li>';
    }
}
echo '</ul>';

Solution 17 - Php

Late to the show, but to build off of the accepted answer...

If you want to have all the files and directories in as array (that can be prettied-up nicely with JSON.stringify in javascript), you can modify the function to:

function listFolderFiles($dir) { 
    $arr = array();
	$ffs = scandir($dir);
    
    foreach($ffs as $ff) {
        if($ff != '.' && $ff != '..') {
            $arr[$ff] = array();
            if(is_dir($dir.'/'.$ff)) {
				$arr[$ff] = listFolderFiles($dir.'/'.$ff);
			}
        }
    }
	
	return $arr;
}

For the Newbies...

To use the aforementioned JSON.stringify, your JS/jQuery would be something like:

var ajax = $.ajax({
	method: 'POST',
	data: {list_dirs: true}
}).done(function(msg) {
	$('pre').html(
		'FILE LAYOUT<br/>' + 
		    JSON.stringify(JSON.parse(msg), null, 4)
	);
});

^ This is assuming you have a <pre> element in your HTML somewhere. Any flavour of AJAX will do, but I figure most people are using something similar to the jQuery above.

And the accompanying PHP:

if(isset($_POST['list_dirs'])) {
	echo json_encode(listFolderFiles($rootPath));
	exit();
}

where you already have listFolderFiles from before.

In my case, I've set my $rootPath to the root directory of the site...

$rootPath; 
if(!isset($rootPath)) {
	$rootPath = $_SERVER['DOCUMENT_ROOT'];
}

The end result is something like...

|    some_file_1487.smthng    []
|    some_file_8752.smthng    []
|    CSS    
|    |    some_file_3615.smthng    []
|    |    some_file_8151.smthng    []
|    |    some_file_7571.smthng    []
|    |    some_file_5641.smthng    []
|    |    some_file_7305.smthng    []
|    |    some_file_9527.smthng    []
|    
|    IMAGES    
|    |    some_file_4515.smthng    []
|    |    some_file_1335.smthng    []
|    |    some_file_1819.smthng    []
|    |    some_file_9188.smthng    []
|    |    some_file_4760.smthng    []
|    |    some_file_7347.smthng    []
|    
|    JSScripts    
|    |    some_file_6449.smthng    []
|    |    some_file_7864.smthng    []
|    |    some_file_3899.smthng    []
|    |    google-code-prettify    
|    |    |    some_file_2090.smthng    []
|    |    |    some_file_5169.smthng    []
|    |    |    some_file_3426.smthng    []
|    |    |    some_file_8208.smthng    []
|    |    |    some_file_7581.smthng    []
|    |    |    some_file_4618.smthng    []
|    |    
|    |    some_file_3883.smthng    []
|    |    some_file_3713.smthng    []

... and so on...

Note: Yours will not look exactly like this - I've modified JSON.stringify to display tabs (vertical pipes), align all keyed values, remove quotes off of keys, and a couple other things. I will modify this answer with a link if I ever get to uploading it, or get enough interest.

Solution 18 - Php

function GetDir($dir) {
    if (is_dir($dir)) {
        if ($kami = opendir($dir)) {
            while ($file = readdir($kami)) {
                if ($file != '.' && $file != '..') {
                    if (is_dir($dir . $file)) {
                        echo $dir . $file;
                        // since it is a directory we recurse it.
                        GetDir($dir . $file . '/');
                    } else {
                        echo $dir . $file;
                    }
                }
            }
        }
        closedir($kami);
    }
}

Solution 19 - Php

This post is for Shef(the one who posted the correct answer). It's the only way I can think of showing him how much I appreciate his code and what I have done with it.

<!DOCTYPE html>
<head><title>Displays Folder Contents</title></head>
<?php

function frmtFolder($Entity){
 echo '<li style="font-weight:bold;color:black;list-style-type:none">' . $Entity;
}

function frmtFile($dEntry, $fEntry){
echo '<li style="list-style-type:square">' . '<a href="' . $dEntry . '/' . $fEntry . 
'"> ' . $fEntry . ' </a>';
}

function listFolderFiles($dir) {
$ffs = scandir($dir);

unset($ffs[array_search('.', $ffs, true)]);
unset($ffs[array_search('..', $ffs, true)]);
unset($ffs[array_search('index.html', $ffs, true)]);
// prevent empty ordered elements
if (count($ffs) < 1) {return;}
echo '<ul>';
foreach ($ffs as $ff) {
    if (is_dir($dir . '/' . $ff)) {
     frmtFolder($dir);
    } else {
     frmtFile($dir, $ff);
    }
    if (is_dir($dir . '/' . $ff)) {
        listFolderFiles($dir . '/' . $ff);
    }
    echo '</li>';
}
echo '</ul>';
}
listFolderFiles('Folder_To_List_Here');

I plan on expanding the frmtFile to use audio and videos tags in the future.

Solution 20 - Php

https://3v4l.org/VsQLb Example Here

function listdirs($dir) {
    static $alldirs = array();
    $dirs = glob($dir . '/*', GLOB_ONLYDIR);
    if (count($dirs) > 0) {
        foreach ($dirs as $d) $alldirs[] = $d;
    }
    foreach ($dirs as $dir) listdirs($dir);
    return $alldirs;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWarriorView Question on Stackoverflow
Solution 1 - PhpShefView Answer on Stackoverflow
Solution 2 - Phpjim_kastrinView Answer on Stackoverflow
Solution 3 - PhpnbauersView Answer on Stackoverflow
Solution 4 - PhpWonderLandView Answer on Stackoverflow
Solution 5 - PhpWesley van OpdorpView Answer on Stackoverflow
Solution 6 - PhpFaisalView Answer on Stackoverflow
Solution 7 - PhppritaeasView Answer on Stackoverflow
Solution 8 - PhpRijkView Answer on Stackoverflow
Solution 9 - PhpVenkatesh PariharView Answer on Stackoverflow
Solution 10 - PhpJustCartyView Answer on Stackoverflow
Solution 11 - PhpSamuel DauzonView Answer on Stackoverflow
Solution 12 - PhplotfioView Answer on Stackoverflow
Solution 13 - PhpSebastian ViereckView Answer on Stackoverflow
Solution 14 - PhpGussView Answer on Stackoverflow
Solution 15 - PhpNeha SinghView Answer on Stackoverflow
Solution 16 - PhpGaurang PView Answer on Stackoverflow
Solution 17 - PhpBirrelView Answer on Stackoverflow
Solution 18 - Phpkamran SheikhView Answer on Stackoverflow
Solution 19 - PhpMyKs3DView Answer on Stackoverflow
Solution 20 - PhpExample OutView Answer on Stackoverflow