146 votes

Comment supprimer récursivement un répertoire et tout son contenu (fichiers + sous-répertoires) en PHP ?

Comment supprimer un répertoire et tout son contenu (fichiers et sous-répertoires) en PHP ?

0 votes

Voici une bonne approche et une bonne solution : stackoverflow.com/a/15111679/2377343

230voto

Artefacto Points 50896

La section contribuée par l'utilisateur dans la page de manuel de rmdir contient une implémentation décente :

 function rrmdir($dir) { 
   if (is_dir($dir)) { 
     $objects = scandir($dir);
     foreach ($objects as $object) { 
       if ($object != "." && $object != "..") { 
         if (is_dir($dir. DIRECTORY_SEPARATOR .$object) && !is_link($dir."/".$object))
           rrmdir($dir. DIRECTORY_SEPARATOR .$object);
         else
           unlink($dir. DIRECTORY_SEPARATOR .$object); 
       } 
     }
     rmdir($dir); 
   } 
 }

1 votes

@The Pixel Developer - J'ai ajouté une réponse montrant que.

2 votes

Consultez la solution que quelqu'un m'a donnée pour la même question : glob semble fonctionner de manière plus agréable : stackoverflow.com/questions/11267086/

0 votes

Cet appel is_dir deux fois pour chaque répertoire récurrent. Si l'argument est un lien symbolique, il le suit également au lieu de supprimer le lien symbolique, ce qui n'est pas forcément ce que vous voulez. Dans tous les cas, ce n'est pas ce que rm -rf ne.

129voto

salathe Points 26305

S'appuyer sur Commentaire du développeur Pixel Un extrait utilisant le SPL pourrait ressembler à ceci :

$files = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
    RecursiveIteratorIterator::CHILD_FIRST
);

foreach ($files as $fileinfo) {
    $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
    $todo($fileinfo->getRealPath());
}

rmdir($dir);

Note : Il n'y a pas de non et utilise le drapeau SKIP_DOTS introduit avec le FilesystemIterator en PHP 5.3.0. Bien sûr, l'option $todo pourrait être un if / else . Le point important est que CHILD_FIRST est utilisé pour itérer sur les enfants (fichiers) avant leurs parents (dossiers).

0 votes

SKIP_DOTS n'a été introduit qu'en PHP 5.3 ? Où avez-vous vu cela ?

1 votes

Nous vous remercions. Par ailleurs, ne devriez-vous pas utiliser l'option getPathname() au lieu de la méthode getRealPath() ?

0 votes

La réponse n'est qu'un exemple générique d'itération sur les fichiers d'abord, puis sur leurs dossiers respectifs.

18voto

Liko Points 256

Supprime tous les fichiers et dossiers du chemin d'accès.

function recurseRmdir($dir) {
  $files = array_diff(scandir($dir), array('.','..'));
  foreach ($files as $file) {
    (is_dir("$dir/$file") && !is_link("$dir/$file")) ? recurseRmdir("$dir/$file") : unlink("$dir/$file");
  }
  return rmdir($dir);
}

1 votes

rm -rf / == recurseRmdir('/') :)

8 votes

Veuillez noter que cette méthode n'est pas sûre pour les liens symboliques ! Vous avez besoin d'une vérification après is_dir pour vérifier également que c'est !is_link, parce que sinon vous pouvez faire un lien symbolique vers un dossier externe qui est ensuite supprimé et cela peut être considéré comme une faille de sécurité. Vous devez donc changer is_dir("$dir/$file") a is_dir("$dir/$file") && !is_link("$dir/$file")

0 votes

Le vrai problème de ce code est que php ne prend pas en charge la récursion, c'est à dire optimisation des appels de queue . La plupart des langages interprétés ne

13voto

ankitjaininfo Points 4395

Pour *nix, vous pouvez utiliser un shell_exec para rm -R ou DEL /S folder_name pour Windows.

3 votes

Comment faire DEL /S folder_name pour Windows

0 votes

@Gordon RMDIR /S /Q folder_name c'est ce qui a fonctionné pour moi

2 votes

@WiR3D tant que la commande exec ne contient pas d'entrée utilisateur, tout devrait bien se passer. Ex : exec('rm -rf ' . __DIR__ . '/output/*.log');

5voto

David Newcomb Points 4685

Il y a un autre fil de discussion avec d'autres exemples ici : Une fonction récursive de suppression de répertoire pour PHP ?

Si vous utilisez Yii, vous pouvez laisser le framework s'en charger :

CFileHelper::removeDirectory($my_directory);

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