web-dev-qa-db-fra.com

Lister tous les dossiers des sous-dossiers et des fichiers d'un répertoire en utilisant php

S'il vous plaît donnez-moi une solution pour lister tous les dossiers, sous-dossiers, fichiers d'un répertoire en utilisant php. Ma structure de dossier est comme ceci:

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

Je veux obtenir la liste de tous les fichiers dans chaque dossier.

Y a-t-il une commande de script shell en php?

53
Warrior
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');
134
Shef

Ce code répertorie tous les répertoires et fichiers par ordre de tri dans une arborescence. C'est un générateur de carte de site avec des hyperliens vers toutes les ressources du site. La source complète de la page Web est ici. Vous aurez besoin de changer le chemin sur la neuvième ligne à partir de la fin.

<?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>
12
nbauers

Si vous voulez utiliser directoryIterator

La fonction suivante est une nouvelle implémentation de @Shef answer avec 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');
10
WonderLand

Une méthode très simple pour afficher la structure de dossiers utilise la classe RecursiveTreeIterator (PHP 5> = 5.3.0, PHP 7) et génère un arbre graphique ASCII.

$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

Il existe également un certain contrôle sur la représentation ASCII de l'arborescence en modifiant les préfixes à l'aide de RecursiveTreeIterator::setPrefixPart, par exemple $it->setPrefixPart(RecursiveTreeIterator::PREFIX_LEFT, "|");.

8
jim_kastrin

J'aime beaucoup la bibliothèque SPL, ils proposent des itérateurs, notamment RecursiveDirectoryIterator .

4
Wesley van Opdorp

Jetez un œil à glob () ou à l'itérateur de répertoire récursif .

2
pritaeas
2
Rijk

Il utilisera pour faire la barre de menu en format de répertoire 

$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>
2
Venkatesh Parihar
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);
    }
}
1
kamran Sheikh

Voici une fonction simple avec scandir & array_filter qui font le travail. filtrer fichiers nécessaires en utilisant regex. J'ai supprimé ... et des fichiers cachés comme .htaccess, vous pouvez également personnaliser la sortie à l'aide de <ul> et de couleurs, ainsi que les erreurs en cas d'erreur de numérisation ou de répertoire vide! 

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');
1

Si vous recherchez un répertoire récursif listant les solutions et organisez-les dans un tableau multidimensionnel. Utilisez le code ci-dessous:

<?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>'

?>
1
Faisal

En retard pour le spectacle, mais pour construire à partir de réponse acceptée ...

Si vous voulez avoir tous les fichiers et répertoires dans un tableau (cela peut être joliment préparé avec JSON.stringify en javascript), vous pouvez modifier la fonction pour:

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;
}

Pour les débutants ...

Pour utiliser le JSON.stringify susmentionné, votre JS/jQuery ressemblerait à quelque chose comme:

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

^ Ceci suppose que vous avez un élément <pre> dans votre code HTML quelque part. N'importe quelle version de AJAX conviendra, mais je suppose que la plupart des gens utilisent quelque chose de similaire au jQuery ci-dessus.

Et le PHP qui l'accompagne:

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

où vous avez déjà listFolderFiles d'avant. 

Dans mon cas, j'ai défini mon $rootPath dans le répertoire racine du site ...

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

Le résultat final est quelque chose comme ...

|    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...

Remarque: vous ne ressemblerez pas exactement à ceci. J'ai modifié JSON.stringify pour afficher des tabulations (tubes verticaux), aligner toutes les valeurs entrées, supprimer les guillemets des clés, etc. lien si je reçois jamais pour le télécharger, ou obtenir assez d'intérêt.

0
Birrel

Vous pouvez aussi essayer ceci:

<?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);
?>
0
Neha Singh

Les réponses précédentes ne répondaient pas à mes besoins.

Si vous voulez tous les fichiers et répertoires dans un tableau plat, vous pouvez utiliser cette fonction (trouvée ici ):

// 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;
}

Dans mon cas : 

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

me retourne un tableau comme celui-ci: 

[
'/home/dir',
'/home/dir/image.png',
'/home/dir/subdir',
'/home/dir/subdir/file.php',
]

Vous pouvez également utiliser la génération de chemin dynamique:

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

Avec cette fonction: 

function os_path_join(...$parts) {
  return preg_replace('#'.DIRECTORY_SEPARATOR.'+#', DIRECTORY_SEPARATOR, implode(DIRECTORY_SEPARATOR, array_filter($parts)));
}

Si vous voulez obtenir uniquement des répertoires, vous pouvez utiliser:

$paths = glob_recursive(os_path_join($base_path, $current_directory, "*"));
$subdirs = array_filter($paths, function($path) {
    return is_dir($path);
});
0
jedema

Cet article est pour Shef (celui qui a posté la bonne réponse). C'est la seule façon pour moi de lui montrer à quel point j'apprécie son code et ce que j'en ai fait.

<!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');

Je prévois d'étendre le fichier frmtFile afin qu'il utilise des balises audio et vidéo à l'avenir.

0
MyKs3D
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>';
0
Gaurang P

Je cherchais une fonction similaire à celle-ci. J'avais besoin de répertoires en tant que clés et de sous-répertoires en tant que tableaux et fichiers pour être simplement placés en tant que valeurs.
J'ai utilisé le code suivant:

/**
 * 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;
}

Il y a beaucoup à prendre.

La première fonction get_files_in_dir a été créée afin que je puisse obtenir tous les fichiers et dossiers d'un répertoire basé sur une expression régulière. Je l'utilise ici car il comporte des erreurs de vérification pour s'assurer qu'un répertoire est converti en tableau.

Ensuite, nous avons une fonction simple qui ajoute une barre oblique à la fin d’une chaîne s’il n’y en a pas déjà une.

Enfin, nous avons la fonction get_directory_tree qui va parcourir tous les dossiers et sous-dossiers et créer un tableau associatif où les noms de dossiers sont les clés et les fichiers sont les valeurs (sauf si le dossier a des sous-dossiers).

0
JustCarty