Je me demande quel est le moyen le plus simple de supprimer un répertoire contenant tous ses fichiers.
J'utilise rmdir(PATH . '/' . $value);
pour supprimer un dossier. Cependant, s'il contient des fichiers, je ne peux simplement pas le supprimer.
Il y a au moins deux options disponibles de nos jours.
Avant de supprimer le dossier, supprimez tous ses fichiers et dossiers (et cela signifie récursivité!). Voici un exemple:
public static function deleteDir($dirPath) {
if (! is_dir($dirPath)) {
throw new InvalidArgumentException("$dirPath must be a directory");
}
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
$dirPath .= '/';
}
$files = glob($dirPath . '*', GLOB_MARK);
foreach ($files as $file) {
if (is_dir($file)) {
self::deleteDir($file);
} else {
unlink($file);
}
}
rmdir($dirPath);
}
Et si vous utilisez 5.2+, vous pouvez utiliser un RecursiveIterator pour le faire sans avoir à faire la récursivité vous-même:
$dir = 'samples' . DIRECTORY_SEPARATOR . 'sampledirtree';
$it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($it,
RecursiveIteratorIterator::CHILD_FIRST);
foreach($files as $file) {
if ($file->isDir()){
rmdir($file->getRealPath());
} else {
unlink($file->getRealPath());
}
}
rmdir($dir);
J'utilise généralement cela pour supprimer tous les fichiers d'un dossier:
array_map('unlink', glob("$dirname/*.*"));
Et alors tu peux faire
rmdir($dirname);
quel est le moyen le plus simple de supprimer un répertoire contenant tous ses fichiers?
system("rm -rf ".escapeshellarg($dir));
Fonction courte qui fait le travail:
function deleteDir($path) {
return is_file($path) ?
@unlink($path) :
array_map(__FUNCTION__, glob($path.'/*')) == @rmdir($path);
}
Je l'utilise dans un cours d'utilitaire comme ceci:
class Utils {
public static function deleteDir($path) {
$class_func = array(__CLASS__, __FUNCTION__);
return is_file($path) ?
@unlink($path) :
array_map($class_func, glob($path.'/*')) == @rmdir($path);
}
}
Un grand pouvoir entraîne une grande responsabilité : Lorsque vous appelez cette fonction avec une valeur vide, elle supprimera les fichiers commençant par la racine (/
). En guise de sauvegarde, vous pouvez vérifier si le chemin est vide:
function deleteDir($path) {
if (empty($path)) {
return false;
}
return is_file($path) ?
@unlink($path) :
array_map(__FUNCTION__, glob($path.'/*')) == @rmdir($path);
}
Ceci est une version plus courte fonctionne très bien pour moi
function deleteDirectory($dirPath) {
if (is_dir($dirPath)) {
$objects = scandir($dirPath);
foreach ($objects as $object) {
if ($object != "." && $object !="..") {
if (filetype($dirPath . DIRECTORY_SEPARATOR . $object) == "dir") {
deleteDirectory($dirPath . DIRECTORY_SEPARATOR . $object);
} else {
unlink($dirPath . DIRECTORY_SEPARATOR . $object);
}
}
}
reset($objects);
rmdir($dirPath);
}
}
Comme indiqué dans la plupart des commentaires votés sur la page de manuel PHP à propos de rmdir()
(voir http://php.net/manual/es/function.rmdir.php ), la fonction glob()
ne renvoie pas les fichiers cachés. scandir()
est fourni à titre d'alternative permettant de résoudre ce problème.
L'algorithme décrit ici (qui a fonctionné comme un charme dans mon cas) est:
<?php
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);
}
?>
Vous pouvez utiliser le système de fichiers de Symfony ( code ):
// composer require symfony/filesystem
use Symfony\Component\Filesystem\Filesystem;
(new Filesystem)->remove($dir);
Cependant, je ne pouvais pas supprimer certaines structures de répertoires complexes avec cette méthode, vous devez donc d'abord l'essayer pour vous assurer qu'elle fonctionne correctement.
Je pourrais supprimer cette structure de répertoire en utilisant une implémentation spécifique à Windows:
$dir = strtr($dir, '/', '\\');
// quotes are important, otherwise one could
// delete "foo" instead of "foo bar"
system('RMDIR /S /Q "'.$dir.'"');
Et juste pour être complet, voici un de mes vieux codes:
function xrmdir($dir) {
$items = scandir($dir);
foreach ($items as $item) {
if ($item === '.' || $item === '..') {
continue;
}
$path = $dir.'/'.$item;
if (is_dir($path)) {
xrmdir($path);
} else {
unlink($path);
}
}
rmdir($dir);
}
Vous avez ici une récursivité simple et agréable pour supprimer tous les fichiers du répertoire source, y compris ce répertoire:
function delete_dir($src) {
$dir = opendir($src);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
delete_dir($src . '/' . $file);
}
else {
unlink($src . '/' . $file);
}
}
}
closedir($dir);
rmdir($src);
}
La fonction est basée sur la récursivité réalisée pour la copie du répertoire. Vous pouvez trouver cette fonction ici: Copier tout le contenu d’un répertoire dans un autre en utilisant php
La fonction Glob ne renvoie pas les fichiers cachés, donc 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);
}
?>
Et ça:
function recursiveDelete($dirPath, $deleteParent = true){
foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirPath, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) {
$path->isFile() ? unlink($path->getPathname()) : rmdir($path->getPathname());
}
if($deleteParent) rmdir($dirPath);
}
Je préfère cela car il retourne toujours TRUE quand il réussit et FALSE quand il échoue, et empêche également un bug où un chemin vide pourrait essayer de tout supprimer de '/ *' !!:
function deleteDir($path)
{
return !empty($path) && is_file($path) ?
@unlink($path) :
(array_reduce(glob($path.'/*'), function ($r, $i) { return $r && deleteDir($i); }, TRUE)) && @rmdir($path);
}
Utiliser DirectoryIterator est l'équivalent d'une réponse précédente…
function deleteFolder($rootPath)
{
foreach(new DirectoryIterator($rootPath) as $fileToDelete)
{
if($fileToDelete->isDot()) continue;
if ($fileToDelete->isFile())
unlink($fileToDelete->getPathName());
if ($fileToDelete->isDir())
deleteFolder($fileToDelete->getPathName());
}
rmdir($rootPath);
}
La meilleure solution pour moi
my_folder_delete("../path/folder");
code:
function my_folder_delete($path) {
if(!empty($path) && is_dir($path) ){
$dir = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS); //upper dirs are not included,otherwise DISASTER HAPPENS :)
$files = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($files as $f) {if (is_file($f)) {unlink($f);} else {$empty_dirs[] = $f;} } if (!empty($empty_dirs)) {foreach ($empty_dirs as $eachDir) {rmdir($eachDir);}} rmdir($path);
}
}
p.s. RAPPELLES TOI!
ne passez pas de valeurs vides à un annuaire en supprimant des fonctions !!! (sauvegardez-les toujours, sinon un jour, vous pourriez avoir une catastrophe!)
Je souhaite développer la réponse de @alcuadrado avec le commentaire de @Vijit pour la gestion des liens symboliques. Tout d'abord, utilisez getRealPath (). Mais ensuite, si vous avez des liens symboliques qui sont des dossiers, cela échouera car il essaiera d'appeler rmdir sur un lien - vous aurez donc besoin d'une vérification supplémentaire.
$it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
foreach($files as $file) {
if ($file->isLink()) {
unlink($file->getPathname());
} else if ($file->isDir()){
rmdir($file->getPathname());
} else {
unlink($file->getPathname());
}
}
rmdir($dir);
Vous pouvez essayer comme suit:
/*
* Remove the directory and its content (all files and subdirectories).
* @param string $dir the directory name
*/
function rmrf($dir) {
foreach (glob($dir) as $file) {
if (is_dir($file)) {
rmrf("$file/*");
rmdir($file);
} else {
unlink($file);
}
}
}
Peu de modifications du code d'alcuadrado - glob
ne voit pas les fichiers portant le nom de points comme .htaccess
, aussi j'utilise scandir et le script se supprime lui-même - cochez __FILE__
.
function deleteDir($dirPath) {
if (!is_dir($dirPath)) {
throw new InvalidArgumentException("$dirPath must be a directory");
}
if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
$dirPath .= '/';
}
$files = scandir($dirPath);
foreach ($files as $file) {
if ($file === '.' || $file === '..') continue;
if (is_dir($dirPath.$file)) {
deleteDir($dirPath.$file);
} else {
if ($dirPath.$file !== __FILE__) {
unlink($dirPath.$file);
}
}
}
rmdir($dirPath);
}
Voici la solution qui fonctionne parfaitement:
function unlink_r($from) {
if (!file_exists($from)) {return false;}
$dir = opendir($from);
while (false !== ($file = readdir($dir))) {
if ($file == '.' OR $file == '..') {continue;}
if (is_dir($from . DIRECTORY_SEPARATOR . $file)) {
unlink_r($from . DIRECTORY_SEPARATOR . $file);
}
else {
unlink($from . DIRECTORY_SEPARATOR . $file);
}
}
rmdir($from);
closedir($dir);
return true;
}
Quelque chose comme ça?
function delete_folder($folder) {
$glob = glob($folder);
foreach ($glob as $g) {
if (!is_dir($g)) {
unlink($g);
} else {
delete_folder("$g/*");
rmdir($g);
}
}
}
2 cents à ajouter à CETTE réponse ci-dessus, ce qui est excellent BTW
Une fois que votre fonction glob (ou similaire) a analysé/lu le répertoire, ajoutez une condition pour vérifier que la réponse n'est pas vide ou un avertissement invalid argument supplied for foreach()
sera émis. Alors...
if( ! empty( $files ) )
{
foreach( $files as $file )
{
// do your stuff here...
}
}
Ma fonction complète (en tant que méthode d'objet):
private function recursiveRemoveDirectory( $directory )
{
if( ! is_dir( $directory ) )
{
throw new InvalidArgumentException( "$directory must be a directory" );
}
if( substr( $directory, strlen( $directory ) - 1, 1 ) != '/' )
{
$directory .= '/';
}
$files = glob( $directory . "*" );
if( ! empty( $files ) )
{
foreach( $files as $file )
{
if( is_dir( $file ) )
{
$this->recursiveRemoveDirectory( $file );
}
else
{
unlink( $file );
}
}
}
rmdir( $directory );
} // END recursiveRemoveDirectory()
Celui-ci fonctionne pour moi:
function removeDirectory($path) {
$files = glob($path . '/*');
foreach ($files as $file) {
is_dir($file) ? removeDirectory($file) : unlink($file);
}
rmdir($path);
return;
}
Pour les fenêtres:
system("rmdir ".escapeshellarg($path) . " /s /q");
Et ça?
function Delete_Directory($Dir)
{
if(is_dir($Dir))
{
$files = glob( $Dir . '*', GLOB_MARK ); //GLOB_MARK adds a slash to directories returned
foreach( $files as $file )
{
Delete_Directory( $file );
}
if(file_exists($Dir))
{
rmdir($Dir);
}
}
elseif(is_file($Dir))
{
unlink( $Dir );
}
}
Référence: https://paulund.co.uk/php-delete-directory-and-files-in-directory
Vous pouvez copier les YII aides
$ directory (string) - à supprimer récursivement.
$ options (array) - pour la suppression du répertoire. Les options valides sont: traverseSymlinks: boolean, si les liens symboliques vers les répertoires doivent également être parcourus. La valeur par défaut est false
, ce qui signifie que le contenu du répertoire lié par un lien symbolique ne sera pas supprimé. Seul le lien symbolique serait supprimé dans ce cas par défaut.
public static function removeDirectory($directory,$options=array())
{
if(!isset($options['traverseSymlinks']))
$options['traverseSymlinks']=false;
$items=glob($directory.DIRECTORY_SEPARATOR.'{,.}*',GLOB_MARK | GLOB_BRACE);
foreach($items as $item)
{
if(basename($item)=='.' || basename($item)=='..')
continue;
if(substr($item,-1)==DIRECTORY_SEPARATOR)
{
if(!$options['traverseSymlinks'] && is_link(rtrim($item,DIRECTORY_SEPARATOR)))
unlink(rtrim($item,DIRECTORY_SEPARATOR));
else
self::removeDirectory($item,$options);
}
else
unlink($item);
}
if(is_dir($directory=rtrim($directory,'\\/')))
{
if(is_link($directory))
unlink($directory);
else
rmdir($directory);
}
}
Si vous n'êtes pas sûr, le chemin donné étant un répertoire ou un fichier, vous pouvez utiliser cette fonction pour supprimer le chemin.
function deletePath($path) {
if(is_file($path)){
unlink($path);
} elseif(is_dir($path)){
$path = (substr($path, -1) !== DIRECTORY_SEPARATOR) ? $path . DIRECTORY_SEPARATOR : $path;
$files = glob($path . '*');
foreach ($files as $file) {
deleteDirPath($file);
}
rmdir($path);
} else {
return false;
}
}
<?php
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);
}
}
?>
Avez-vous essayé le code obove de php.net
Travaille bien pour moi
Exemple pour le serveur Linux: exec('rm -f -r ' . $cache_folder . '/*');
Comme la solution de Playnox, mais avec l'élégant et intégré DirectoryIterator:
function delete_directory($dirPath){
if(is_dir($dirPath)){
$objects=new DirectoryIterator($dirPath);
foreach ($objects as $object){
if(!$object->isDot()){
if($object->isDir()){
delete_directory($object->getPathname());
}else{
unlink($object->getPathname());
}
}
}
rmdir($dirPath);
}else{
throw new Exception(__FUNCTION__.'(dirPath): dirPath is not a directory!');
}
}
Simple et facile...
$dir ='pathtodir';
if (is_dir($dir)) {
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)) as $filename) {
if ($filename->isDir()) continue;
unlink($filename);
}
rmdir($dir);
}
Je ne me souviens pas d'où j'ai copié cette fonction, mais on dirait qu'elle n'est pas répertoriée et qu'elle fonctionne pour moi
function rm_rf($path) {
if (@is_dir($path) && is_writable($path)) {
$dp = opendir($path);
while ($ent = readdir($dp)) {
if ($ent == '.' || $ent == '..') {
continue;
}
$file = $path . DIRECTORY_SEPARATOR . $ent;
if (@is_dir($file)) {
rm_rf($file);
} elseif (is_writable($file)) {
unlink($file);
} else {
echo $file . "is not writable and cannot be removed. Please fix the permission or select a new path.\n";
}
}
closedir($dp);
return rmdir($path);
} else {
return @unlink($path);
}
}
vous pouvez essayer cette simple ligne de code de 12 lignes pour supprimer des dossiers ou des dossiers de dossiers ... codage heureux ...;) :)
function deleteAll($str) {
if (is_file($str)) {
return unlink($str);
}
elseif (is_dir($str)) {
$scan = glob(rtrim($str,'/').'/*');
foreach($scan as $index=>$path) {
$this->deleteAll($path);
}
return @rmdir($str);
}
}