web-dev-qa-db-fra.com

Une fonction de répertoire de suppression récursive pour PHP?

J'utilise PHP pour déplacer le contenu d'un sous-dossier images

GalleryName/images /

dans un autre dossier. Après le déménagement, je dois supprimer le répertoire GalleryName et tout le reste à l'intérieur .

Je sais que rmdir() ne fonctionnera que si le répertoire est vide. J'ai passé un certain temps à essayer de créer une fonction récursive pour scandir() en partant du haut, puis de unlink() s'il s'agit d'un fichier et de scandir() s'il s'agit d'un répertoire, puis de rmdir() chaque répertoire vide comme je le fais.

Jusqu’à présent, cela ne fonctionnait pas très bien et j’ai commencé à penser - n’est-ce pas une fonction ridiculement simple que PHP devrait être capable de faire? Supprimer un répertoire?

Alors, y a-t-il quelque chose qui me manque? Ou y a-t-il au moins une fonction prouvée que les gens utilisent pour cette action?

Toute aide serait appréciée.

PS Je vous fais tous confiance ici plus que les commentaires sur le site php.net - il y a des centaines de fonctions là-bas mais je serais intéressé de savoir si l'un d'entre vous en recommande une au détriment des autres.

26
rhodesjason

Qu'en est-il de ce problème?

foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirPath, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) {
        $path->isDir() && !$path->isLink() ? rmdir($path->getPathname()) : unlink($path->getPathname());
}
rmdir($dirPath);
84
barbushin

C'est la fonction récursive que j'ai créée/modifiée et qui semble enfin fonctionner. Espérons qu'il n'y a rien de trop dangereux.

function destroy_dir($dir) { 
    if (!is_dir($dir) || is_link($dir)) return unlink($dir); 
    foreach (scandir($dir) as $file) { 
        if ($file == '.' || $file == '..') continue; 
        if (!destroy_dir($dir . DIRECTORY_SEPARATOR . $file)) { 
            chmod($dir . DIRECTORY_SEPARATOR . $file, 0777); 
            if (!destroy_dir($dir . DIRECTORY_SEPARATOR . $file)) return false; 
        }; 
    } 
    return rmdir($dir); 
} 
14
rhodesjason

Si le serveur de l'application exécute Linux, utilisez simplement la fonction Shell_exec () et fournissez-lui la commande rm -R, comme ceci:

Shell_exec("rm ".$dir_path." -R");

Explication:

La fonction lancera la commande insérée directement dans linux. C'est exactement la même chose que lancer la commande dans un terminal linux.

La commande rm supprime un fichier ou un répertoire passé dans $dir_path et l'option -R indique à Le système pour l'exécuter de manière récursive.

2
Gabriel Guelfi

J'ai adapté une fonction qui gère les fichiers Unix cachés avec le préfixe point et utilise glob:

public static function deleteDir($path) {
    if (!is_dir($path)) {
        throw new InvalidArgumentException("$path is not a directory");
    }
    if (substr($path, strlen($path) - 1, 1) != '/') {
        $path .= '/';
    }
    $dotfiles = glob($path . '.*', GLOB_MARK);
    $files = glob($path . '*', GLOB_MARK);
    $files = array_merge($files, $dotfiles);
    foreach ($files as $file) {
        if (basename($file) == '.' || basename($file) == '..') {
            continue;
        } else if (is_dir($file)) {
            self::deleteDir($file);
        } else {
            unlink($file);
        }
    }
    rmdir($path);
}
0
Aram Kocharyan
public static function rrmdir($dir)
{
    if (is_dir($dir)) {
        $files = scandir($dir);
        foreach ($files as $file) {
            if ($file != "." && $file != "..") {
                if (filetype($dir . "/" . $file) == "dir")
                    self::rrmdir($dir . "/" . $file);
                else
                    unlink($dir . "/" . $file);
            }
        }
        reset($files);
        rmdir($dir);
    }
}
0
yousef

Il y a un autre fil avec plus d'exemples ici: Comment supprimer récursivement un répertoire et tout son contenu (fichiers + sous-répertoires) en PHP?

Si vous utilisez Yii, vous pouvez le laisser dans le cadre:

CFileHelper::removeDirectory($my_directory);
0
David Newcomb

Je préfère une méthode enrichie dérivée des pages d'aide de php http://php.net/manual/en/function.rmdir.php#115598

 // check accidential empty, root or relative pathes
 if (!empty($path) && ...)
 {
  if (PHP_OS === 'Windows')
  {
    exec('rd /s /q "'.$path.'"');
  }
  else
  {
      exec('rm -rf "'.$path.'"');
  }
}
else
{
    error_log('path not valid:$path'.var_export($path, true));
}

raisons de ma décision:

  • moins de code
  • la vitesse
  • rester simple
0
user1680948