19 votes

Tableau récursif profond de la structure des répertoires en PHP

J'essaie de mettre certains dossiers de mon disque dur dans un tableau.

Par exemple, des photos de vacances. Disons que nous avons cette structure :

  • Set 1
    • Point 1 de l'ensemble 1
    • Point 2 de l'ensemble 1
    • Article ... de l'ensemble 1
  • Ensemble 2
    • Sous-ensemble 1 de l'ensemble 2
      • Élément 1 du sous-ensemble 1 de l'ensemble 2
      • Item ... du sous-ensemble 1 de l'ensemble 2
    • Sous-ensemble 2 de l'ensemble 2
    • Fichier aléatoire, pas un répertoire.
  • Ensemble 3
  • ...

Je veux avoir quelque chose comme ça, sous forme de tableau.
Cela signifie que j'ai un grand tableau et que ce tableau contient d'autres tableaux. Chaque ensemble et sous-ensemble a son propre tableau.

J'essaie de faire en sorte que ça ressemble à quelque chose comme ça :

Array
(
    [Set 1] => Array([0] => Item 1 of Set 1, [1] => Item 1 of Set 1,...)
    [Set 2] => Array([Subnet 1] => Array([0] => Item 1 of Subset 1 of Set 2,[1] => ...), [Subnet 2] => Array([0] => ..., ..., ...), ..., [0] => Random File)
    [set 3] => Array(...)
    ...
)

Je suis tombé sur ça : http://www.the-art-of-web.com/php/dirlist/

Mais ce n'est pas ce que je recherche. Je m'en suis mêlé mais ça ne m'a apporté que des ennuis.

Voici un exemple, voir la source pour une plus grande résolution (pas de clic apparemment...). Example

46voto

Peter Bailey Points 62125

Je recommande d'utiliser Itérateur de répertoire pour construire votre tableau

Voici un extrait que j'ai assemblé très rapidement, mais je n'ai pas d'environnement pour le tester actuellement, alors préparez-vous à le déboguer.

$fileData = fillArrayWithFileNodes( new DirectoryIterator( '/path/to/root/' ) );

function fillArrayWithFileNodes( DirectoryIterator $dir )
{
  $data = array();
  foreach ( $dir as $node )
  {
    if ( $node->isDir() && !$node->isDot() )
    {
      $data[$node->getFilename()] = fillArrayWithFileNodes( new DirectoryIterator( $node->getPathname() ) );
    }
    else if ( $node->isFile() )
    {
      $data[] = $node->getFilename();
    }
  }
  return $data;
}

14voto

soulmerge Points 37314

Une mise en œuvre simple sans aucune gestion des erreurs :

function dirToArray($dir) {
    $contents = array();
    # Foreach node in $dir
    foreach (scandir($dir) as $node) {
        # Skip link to current and parent folder
        if ($node == '.')  continue;
        if ($node == '..') continue;
        # Check if it's a node or a folder
        if (is_dir($dir . DIRECTORY_SEPARATOR . $node)) {
            # Add directory recursively, be sure to pass a valid path
            # to the function, not just the folder's name
            $contents[$node] = dirToArray($dir . DIRECTORY_SEPARATOR . $node);
        } else {
            # Add node, the keys will be updated automatically
            $contents[] = $node;
        }
    }
    # done
    return $contents;
}

6voto

tim Points 1385

Basé sur le code de La réponse de @soulmerge . J'ai juste enlevé quelques mites et les commentaires et l'utilisation $startpath comme répertoire de départ. (MERCI @soulmerge !)

function dirToArray($dir) {
    $contents = array();
    foreach (scandir($dir) as $node) {
        if ($node == '.' || $node == '..') continue;
        if (is_dir($dir . '/' . $node)) {
            $contents[$node] = dirToArray($dir . '/' . $node);
        } else {
            $contents[] = $node;
        }
    }
    return $contents;
}

$r = dirToArray($startpath);
print_r($r);

2voto

Michael Johnson Points 1474

J'ai eu du succès avec le paquet PEAR File_Find, spécifiquement la méthode mapTreeMultiple() . Votre code deviendrait quelque chose comme :

require_once 'File/Find.php';
$fileList = File_Find::mapTreeMultiple($dirPath);

Cela devrait renvoyer un tableau similaire à celui que vous demandez.

0voto

modnarrandom Points 90

Alors 6 ans plus tard....

J'avais besoin d'une solution comme les réponses de @tim & @soulmerge. J'essayais de faire des modèles de tests unitaires php en vrac pour tous les fichiers php dans les dossiers par défaut de Codeigniter.

C'était la première étape de mon processus, pour obtenir le contenu récursif complet d'un répertoire / dossier sous forme de tableau. Puis recréer la structure de fichiers, et à l'intérieur des répertoires, avoir des fichiers avec le bon nom, la structure de classe, les parenthèses, les méthodes et les sections de commentaires prêts à être remplis pour le php UnitTest.

Pour résumer : donnez un nom de répertoire, obtenez un tableau à une seule couche de tous les répertoires qu'il contient comme clés et tous les fichiers qu'il contient comme valeurs.

J'ai élargi un peu plus leur réponse et vous obtenez ce qui suit :

function getPathContents($path)
{
     // was a file path provided?
     if ($path === null){
        // default file paths in codeigniter 3.0
        $dirs = array(
            './models',
            './controllers'
        );
    } else{
        // file path was provided
        // it can be a comma separated list or singular filepath or file
        $dirs = explode(',', $path);
    }
    // final array
    $contents = array();
    // for each directory / file given
    foreach ($dirs as $dir) {
        // is it a directory?
        if (is_dir($dir)) {
            // scan the directory and for each file inside
            foreach (scandir($dir) as $node) {
                // skip current and parent directory
                if ($node === '.' || $node === '..') {
                    continue;
                } else {
                    // check for sub directories
                    if (is_dir($dir . '/' . $node)) {
                        // recursive check for sub directories
                        $recurseArray = getPathContents($dir . '/' . $node);
                        // merge current and recursive results
                        $contents = array_merge($contents, $recurseArray);
                    } else {
                        // it a file, put it in the array if it's extension is '.php'
                        if (substr($node, -4) === '.php') {
                            // don'r remove periods if current or parent directory was input
                            if ($dir === '.' || $dir === '..') {
                                $contents[$dir][] = $node;
                            } else {
                                // remove period from directory name 
                                $contents[str_replace('.', '', $dir)][] = $node;
                            }
                        }
                    }
                }
            }
        } else {
            // file name was given
            $contents[] = $dir; 
        }
    }
    return $contents;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X