Alors ouais: Aujourd'hui, j'étais flemmard et googled pour une solution de coupe de biscuit à une liste de répertoires récursifs et suis tombé sur ceci. Comme j'ai fini par écrire ma propre fonction (pourquoi j'ai même passé du temps à Google pour cela est au-delà de moi - je ressens toujours le besoin de réinventer la roue sans raison valable) je me sentais enclin à partager ma prise sur ce. Bien qu'il y ait des opinions pour et contre l'utilisation de RecursiveDirectoryIterator, je posterai simplement mon opinion sur une simple fonction de répertoire récursif et éviterai les politiques de s'interrompre sur RecursiveDirectoryIterator.
Ici, il est:
function recursiveDirectoryList($root)
{
/*
* this next conditional isn't required for the code to function, but I
* did not want double directory separators in the resulting array values
* if a trailing directory separator was provided in the root path;
* this seemed an efficient manner to remedy said problem easily...
*/
if(substr($root, -1) === DIRECTORY_SEPARATOR)
{
$root = substr($root, 0, strlen($root) - 1);
}
if(! is_dir($root)) return array();
$files = array();
$dir_handle = opendir($root);
while(($entry = readdir($dir_handle)) !== false)
{
if($entry === '.' || $entry === '..') continue;
if(is_dir($root . DIRECTORY_SEPARATOR . $entry))
{
$sub_files = recursiveDirectoryList(
$root .
DIRECTORY_SEPARATOR .
$entry .
DIRECTORY_SEPARATOR
);
$files = array_merge($files, $sub_files);
}
else
{
$files[] = $root . DIRECTORY_SEPARATOR . $entry;
}
}
return (array) $files;
}
Avec cette fonction, la réponse à l'obtention d'un nombre de fichiers est simple:
$dirpath = '/your/directory/path/goes/here/';
$files = recursiveDirectoryList($dirpath);
$number_of_files = sizeof($files);
Mais, si vous ne voulez pas les frais généraux d'un tableau des chemins de fichier respectifs - ou n'en ont tout simplement pas besoin - il n'est pas nécessaire de transmettre un nombre à la fonction récursive comme cela a été recommandé.
On pourrait simplement modifier ma fonction d'origine pour effectuer le comptage en tant que tel:
function recursiveDirectoryListC($root)
{
$count = 0;
if(! is_dir($root)) return (int) $count;
$dir_handle = opendir($root);
while(($entry = readdir($dir_handle)) !== false)
{
if($entry === '.' || $entry === '..') continue;
if(is_dir($root . DIRECTORY_SEPARATOR . $entry))
{
$count += recursiveDirectoryListC(
$root .
DIRECTORY_SEPARATOR .
$entry .
DIRECTORY_SEPARATOR
);
}
else
{
$count++;
}
}
return (int) $count;
}
fonction
la opendir() Dans ces deux fonctions devrait vraiment être enveloppé dans une condition dans le cas où le répertoire est pas lisible ou une autre erreur se produit. Assurez-vous de le faire correctement:
if(($dir_handle = opendir($dir)) !== false)
{
/* perform directory read logic */
}
else
{
/* do something on failure */
}
Hope this helps quelqu'un ...
Juste une remarque: un itérateur fait ce que son nom l'indique. Il itére sur une source itérable. Ce n'est pas différent d'itérer sur un tableau. Si vous voulez que les résultats soient triés, vous devrez le faire dans la boucle foreach ou écrire/utiliser une fonction pour le faire pour vous. – Gordon
@Gordon vrai. Mais être capable d'obtenir les résultats triés et/ou filtrés tout de suite est une fonctionnalité que j'attendrais néanmoins d'un itérateur de répertoire récursif - je comprends que cela ne soit pas dans l'esprit du SPL, mais quand même. En l'état actuel des choses, il est nécessaire de créer des douzaines de lignes de code (avec des centaines d'extraits sur le réseau, toutes de qualité variable) pour effectuer une tâche standard, où d'autres langages offrent des fonctions toutes prêtes. Ça m'énerve parfois. –
@Pekka Puisque tout peut être un Iterable maintenant, il est impossible de trouver un genre générique. Comment devrait-il savoir que je veux que mes objets Person soient triés par $ firstName mais mes fichiers par MTime? Vous * devez * écrire ceci. Si vous voulez interroger des objets par des expressions génériques, jetez un oeil à PHPLinq. – Gordon