J'essaie de supprimer un répertoire avec rmdir
, mais j'ai reçu le message "Répertoire non vide", car il contient toujours des fichiers.
Quelle fonction puis-je utiliser pour supprimer un répertoire contenant tous les fichiers qu'il contient?
Il n’existe pas de fonction intégrée permettant de faire cela, mais consultez les commentaires au bas de http://us3.php.net/rmdir . Un certain nombre de commentateurs ont publié leurs propres fonctions de suppression de répertoire récursive. Vous pouvez faire votre choix parmi ceux-ci.
Voici celui qui a l'air décent :
function deleteDirectory($dir) {
if (!file_exists($dir)) {
return true;
}
if (!is_dir($dir)) {
return unlink($dir);
}
foreach (scandir($dir) as $item) {
if ($item == '.' || $item == '..') {
continue;
}
if (!deleteDirectory($dir . DIRECTORY_SEPARATOR . $item)) {
return false;
}
}
return rmdir($dir);
}
Edit: Vous pouvez simplement appeler rm -rf
si vous voulez garder les choses simples. Cela rend votre script uniquement sous UNIX, alors méfiez-vous de cela. Si vous y allez, j'essaierais quelque chose comme:
function deleteDirectory($dir) {
system('rm -rf ' . escapeshellarg($dir), $retval);
return $retval == 0; // UNIX commands return zero on success
}
Vous pouvez toujours essayer d'utiliser des commandes système.
Si vous utilisez Linux, utilisez: rm -rf /dir
Si vous utilisez Windows, utilisez: rd c:\dir /S /Q
Dans le message ci-dessus ( John Kugelman ), je suppose que l’analyseur PHP optimisera ce scandir dans le foreach, mais il me semble tout simplement faux que la variable scandir
soit définie dans la condition foreach
.
Vous pouvez également simplement exécuter deux commandes array_shift
pour supprimer les .
et ..
au lieu de toujours vérifier la boucle.
function rrmdir($dir) {
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (filetype($dir."/".$object) == "dir"){
rrmdir($dir."/".$object);
}else{
unlink($dir."/".$object);
}
}
}
reset($objects);
rmdir($dir);
}
}
Ne peut pas penser à un moyen plus facile et plus efficace de le faire que cela
<?php
$dirname = './myfolder';
if (is_dir($dirname)) {
$dir = new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS);
foreach (new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST ) as $filename => $file) {
if (is_file($filename))
unlink($filename);
else
rmdir($filename);
}
rmdir($dirname); // Now remove myfolder
}
?>
Je ne suis pas arrivé à supprimer un dossier car PHP m'a dit qu'il n'était pas vide. Mais c'était. La fonction de Naman était la bonne solution pour compléter le mien. Alors voici ce que j'utilise:
function emptyDir($dir) {
if (is_dir($dir)) {
$scn = scandir($dir);
foreach ($scn as $files) {
if ($files !== '.') {
if ($files !== '..') {
if (!is_dir($dir . '/' . $files)) {
unlink($dir . '/' . $files);
} else {
emptyDir($dir . '/' . $files);
rmdir($dir . '/' . $files);
}
}
}
}
}
}
function deleteDir($dir) {
foreach(glob($dir . '/' . '*') as $file) {
if(is_dir($file)){
deleteDir($file);
} else {
unlink($file);
}
}
emptyDir($dir);
rmdir($dir);
}
Donc, pour supprimer un répertoire et récursivement son contenu:
deleteDir($dir);
Mon cas comportait quelques répertoires compliqués (noms contenant des caractères spéciaux, imbrication profonde, etc.) et des fichiers cachés générant des erreurs "Répertoire non vide" avec d'autres solutions suggérées. Comme une solution Unix seulement était inacceptable, j'ai testé jusqu'à arriver à la solution suivante (qui a bien fonctionné dans mon cas):
function removeDirectory($path) {
// The preg_replace is necessary in order to traverse certain types of folder paths (such as /dir/[[dir2]]/dir3.abc#/)
// The {,.}* with GLOB_BRACE is necessary to pull all hidden files (have to remove or get "Directory not empty" errors)
$files = glob(preg_replace('/(\*|\?|\[)/', '[$1]', $path).'/{,.}*', GLOB_BRACE);
foreach ($files as $file) {
if ($file == $path.'/.' || $file == $path.'/..') { continue; } // skip special dir entries
is_dir($file) ? removeDirectory($file) : unlink($file);
}
rmdir($path);
return;
}
Voici ce que j'ai utilisé:
function emptyDir($dir) {
if (is_dir($dir)) {
$scn = scandir($dir);
foreach ($scn as $files) {
if ($files !== '.') {
if ($files !== '..') {
if (!is_dir($dir . '/' . $files)) {
unlink($dir . '/' . $files);
} else {
emptyDir($dir . '/' . $files);
rmdir($dir . '/' . $files);
}
}
}
}
}
}
$dir = 'link/to/your/dir';
emptyDir($dir);
rmdir($dir);
Avec cette fonction, vous pourrez supprimer n'importe quel fichier ou dossier
function deleteDir($dirPath)
{
if (!is_dir($dirPath)) {
if (file_exists($dirPath) !== false) {
unlink($dirPath);
}
return;
}
if ($dirPath[strlen($dirPath) - 1] != '/') {
$dirPath .= '/';
}
$files = glob($dirPath . '*', GLOB_MARK);
foreach ($files as $file) {
if (is_dir($file)) {
deleteDir($file);
} else {
unlink($file);
}
}
rmdir($dirPath);
}
Essayez la fonction pratique suivante:
/**
* Removes directory and its contents
*
* @param string $path Path to the directory.
*/
function _delete_dir($path) {
if (!is_dir($path)) {
throw new InvalidArgumentException("$path must be a directory");
}
if (substr($path, strlen($path) - 1, 1) != DIRECTORY_SEPARATOR) {
$path .= DIRECTORY_SEPARATOR;
}
$files = glob($path . '*', GLOB_MARK);
foreach ($files as $file) {
if (is_dir($file)) {
_delete_dir($file);
} else {
unlink($file);
}
}
rmdir($path);
}
De http://php.net/manual/en/function.rmdir.php#91797
La fonction Glob ne renvoie pas les fichiers cachés. Par conséquent, scandir peut être plus utile lorsque vous essayez de supprimer de manière récursive un arbre.
<?php
public static function delTree($dir) {
$files = array_diff(scandir($dir), array('.','..'));
foreach ($files as $file) {
(is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
}
return rmdir($dir);
}
?>