rmdir

(PHP 3, PHP 4, PHP 5)

rmdir -- 删除目录

说明

bool rmdir ( string dirname )

尝试删除 dirname 所指定的目录。 该目录必须是空的,而且要有相应的权限。如果成功则返回 TRUE,失败则返回 FALSE

注: 自 PHP 5.0.0 起 rmdir() 也可用于某些 URL 封装协议。参见附录 L 的列表看看 rmdir() 支持哪些 URL 封装协议。

注: 对 context 的支持是 PHP 5.0.0 添加的。有关 context 的说明请参考参考 CXLI, Stream Functions

注: 安全模式被激活时,PHP 将检查被操作的目录是否和正在执行的脚本有相同的 UID(所有者)。

参见 mkdir()unlink()


add a note add a note User Contributed Notes
sarangan dot thuraisingham at gmail dot com
04-Nov-2006 04:52
I installed Joomla CMS and the files where under apache user. So I couldn't delete from my SSH login. Your little function helped. But, you forgot about hidden files in Unix. Filenames beginning with a . are not returned in the glob list. So the modified code looks like this:

<?php
function removeDir($path) {
  
// Add trailing slash to $path if one is not there
  
if (substr($path, -1, 1) != "/") {
      
$path .= "/";
   }

  
$normal_files = glob($path . "*");
  
$hidden_files = glob($path . "\.?*");
  
$all_files = array_merge($normal_files, $hidden_files);

   foreach (
$all_files as $file) {
      
# Skip pseudo links to current and parent dirs (./ and ../).
      
if (preg_match("/(\.|\.\.)$/", $file))
       {
               continue;
       }

       if (
is_file($file) === TRUE) {
          
// Remove each file in this Directory
          
unlink($file);
           echo
"Removed File: " . $file . "<br>";
       }
       else if (
is_dir($file) === TRUE) {
          
// If this Directory contains a Subdirectory, run this Function on it
          
removeDir($file);
       }
   }
  
// Remove Directory once Files have been removed (If Exists)
  
if (is_dir($path) === TRUE) {
      
rmdir($path);
       echo
"<br>Removed Directory: " . $path . "<br><br>";
   }
}

#To remove a dir:
removeDir('/home/fhlinux206/t/thuraisingham.net/tmp/');
?>
FormatThis
19-Oct-2006 11:47
@ null at php5 dot pl & stijnleenknegt< at >gmail< dot >com & mediengestalter at gleichjetzt dot de:
[EDITORS NOTE: Mentioned Notes have all been Removed (Previous Examples)]

I believe the following is what you were trying to make happen.  notes and echo commands have been added so you can see what is being done as it happens and also threw in the actual rmdir function so that the directories as well will be removed and not just the files.

<?php
function removeDir($path) {
  
// Add trailing slash to $path if one is not there
  
if (substr($path, -1, 1) != "/") {
      
$path .= "/";
   }
   foreach (
glob($path . "*") as $file) {
       if (
is_file($file) === TRUE) {
          
// Remove each file in this Directory
          
unlink($file);
           echo
"Removed File: " . $file . "<br>";
       }
       else if (
is_dir($file) === TRUE) {
          
// If this Directory contains a Subdirectory, run this Function on it
          
removeDir($file);
       }
   }
  
// Remove Directory once Files have been removed (If Exists)
  
if (is_dir($path) === TRUE) {
      
rmdir($path);
       echo
"<br>Removed Directory: " . $path . "<br><br>";
   }
}
?>
les_diadoques at worldonline dot fr
06-Jun-2006 04:00
For PHP 3-4-5.
No trailing "/" at the end of the path.

<?php

function remove_directory($dir) {
  if (
$handle = opendir("$dir")) {
   while (
false !== ($item = readdir($handle))) {
     if (
$item != "." && $item != "..") {
       if (
is_dir("$dir/$item")) {
        
remove_directory("$dir/$item");
       } else {
        
unlink("$dir/$item");
         echo
" removing $dir/$item<br>\n";
       }
     }
   }
  
closedir($handle);
  
rmdir($dir);
   echo
"removing $dir<br>\n";
  }
}

remove_directory("/path/to/dir");

?>
brianleeholub at yahoo dot com
12-May-2006 02:30
this will only work in php5 (scandir).

feed this function the path to a directory (INCLUDE TRAILING /) and it'll clean it of all contents (if it contains a directory with more stuff it'll dive down and clean that out). use with care!

remove_directory('/path/to/crap/for/deletion/');

function remove_directory($dir) {
       $dir_contents = scandir($dir);
       foreach ($dir_contents as $item) {
           if (is_dir($dir.$item) && $item != '.' && $item != '..') {
               remove_directory($dir.$item.'/');
           }
           elseif (file_exists($dir.$item) && $item != '.' && $item != '..') {
               unlink($dir.$item);
           }
       }
       rmdir($dir);
   }
not at any dot com
15-Apr-2006 02:21
Save some time, if you want to clean a directory or delete it and you're on windows.

Use This:

           chdir ($file_system_path);
           exec ("del *.* /s /q");

You can use other DEL syntax, or any other shell util.
You may have to allow the service to interact with the desktop, as that's my current setting and I'm not changing it to test this.
dao at design-noir.de
19-Feb-2006 07:17
[bobbfwed at comcast dot net], you posted really bad code. The constant and the global variable are absolutely useless and make the function inflexible and fault-prone. Furthermore your error echo'ing is weird, you should use trigger_error().

Now, since previous rmdirr() implementations lack the ability to simply clear a directory and ClearDirectory() / RemoveDirectory() by [mn dot yarar at gmail dot com] didn't work with nested directories, I've rewritten them: http://en.design-noir.de/webdev/PHP/rmdirr_cleardir/
bobbfwed at comcast dot net
03-Feb-2006 03:20
I have programmed a really nice program that remotely lets you manage files as if you have direct access to them (http://sourceforge.net/projects/filemanage/). I have a bunch of really handy functions to do just about anything to files or directories. In it I use this directory delete function.
Here is the function I made; it will likely need tweaking to work as a standalone script, since it relies of variables set by my program (eg: loc1 -- which dynamically changes in my program):

<?PHP

 
// loc1 is the path on the computer to the base directory that may be moved
define('loc1', 'C:/Program Files/Apache Group/Apache/htdocs', true);

 
// use this format:
$dir = '[reletive path]';
if(
remdir($dir))
 
rmdir($dir);
else
  echo
'There was an error.';

 
// this function deletes all files and sub directories directories in a directory
  // bool remdir( str 'directory path' )
function remdir($dir){

  if(!isset(
$GLOBALS['remerror']))
  
$GLOBALS['remerror'] = false;

  if(
$handle = opendir(loc1 . $dir)){          // if the folder exploration is sucsessful, continue
  
while (false !== ($file = readdir($handle))){ // as long as storing the next file to $file is successful, continue
    
$path = $dir . '/' . $file;
     if(
is_file(loc1 . $path)){
       if(!
unlink(loc1 . $path)){
         echo
'<u><font color="red">"' . $path . '" could not be deleted. This may be due to a permissions problem.</u><br>Directory cannot be deleted until all files are deleted.</font><br>';
        
$GLOBALS['remerror'] = true;
         return
false;
       }
     } else
     if(
is_dir(loc1 . $path) && substr($file, 0, 1) != '.'){
      
remdir($path);
       @
rmdir(loc1 . $path);
     }
   }
  
closedir($handle); // close the folder exploration
 
}

  if(!
$GLOBALS['remerror']) // if no errors occured, delete the now empty directory.
  
if(!rmdir(loc1 . $dir)){
     echo
'<b><font color="red">Could not remove directory "' . $dir . '". This may be due to a permissions problem.</font></b><br>';
     return
false;
   } else
     return
true;

  return
false;
}
// end of remdir()
?>

This new function will be in 0.9.7 (the current release of File Manage) which was just released.
Hope this helps some people.
mn dot yarar at gmail dot com
02-Feb-2006 06:36
/***********************************
Author : M. Niyazi Yarar
Created : February, 2006
Description : Simply clean files
and removes the directory

If any error occurs or for your suggestions,
please send me e-mail
***********************************/
function ClearDirectory($path){
   if($dir_handle = opendir($path)){   
       while($file = readdir($dir_handle)){   
           if($file == "." || $file == ".."){
               if(!@unlink($path."/".$file)){
                   continue;
               }               
           }else{
               @unlink($path."/".$file);
           }
       }
       closedir($dir_handle);
       return true;
// all files deleted
   }else{
       return false;
// directory doesnt exist
   }   
}
function RemoveDirectory($path){
   if(ClearDirectory($path)){
       if(rmdir($path)){
           return true;
// directory removed
       }else{
           return false;
// directory couldnt removed
       }
   }else{
       return false;
// no empty directory
   }
}
/***************************************
Example Usage

if(RemoveDirectory("/mysite/images")){
   echo 'Uughh! All images gone!';
}else{
   echo 'Ohh, well done. I am so lucky';
}
***************************************/
Andreas Kalsch (akidee.de)
03-Jan-2006 03:43
a function that deletes a directory - beginning with the deepest directory and its files.

- it really works if you have enough rights.
- it returns a boolean value if everything is properly done.

function deleteDir($dir)
{
   if (substr($dir, strlen($dir)-1, 1) != '/')
       $dir .= '/';

   echo $dir;

   if ($handle = opendir($dir))
   {
       while ($obj = readdir($handle))
       {
           if ($obj != '.' && $obj != '..')
           {
               if (is_dir($dir.$obj))
               {
                   if (!deleteDir($dir.$obj))
                       return false;
               }
               elseif (is_file($dir.$obj))
               {
                   if (!unlink($dir.$obj))
                       return false;
               }
           }
       }

       closedir($handle);

       if (!@rmdir($dir))
           return false;
       return true;
   }
   return false;
}
almann
30-Nov-2005 11:06
some systems coudnd erase directorys while they are open. So its better to set @closedir($dh); before trying to erase with @rmdir($dir);
stefano at takys dot it
24-Nov-2005 10:26
becouse all the examples fails if there are hiddenfiles (.filename) somewhere, I write this short and power function to erase a tree independtly from his content

/**
 * rm() -- Very Vigorously erase files and directories. Also hidden files !!!!
 *
 * @param $dir string
 *                  be carefull to:
 *                        if($obj=='.' || $obj=='..') continue;
 *                    if not it will erase all the server...it happened to me ;)
 *                    the function is permission dependent.   
 */
function rm($dir) {
   if(!$dh = @opendir($dir)) return;
   while (($obj = readdir($dh))) {
       if($obj=='.' || $obj=='..') continue;
       if (!@unlink($dir.'/'.$obj)) rm($dir.'/'.$obj);
   }
   @rmdir($dir);
}
andy at mentalist dot co dot uk
17-Nov-2005 06:17
# Clears temporary directory and any files or sub directories
# using a stack, without evil recursion.
#
# Andy Gale - 17/11/2005

function clear_tmp_dir($dir)
{
   $stack = array($dir);

   while (count($stack)) {
       # Get last directory on stack
       $dir = end($stack);
      
       $dh = opendir($dir);
       if (!$dh) {
           trigger_error('clear_tmp_dir: unable to opendir ' . $dir, E_USER_ERROR);
       }
      
       while (($file = readdir($dh)) !== false) {
           if ($file == '.' or $file == '..') {
               continue;
           }

           if (is_dir($dir . DIRECTORY_SEPARATOR . $file)) {
               $stack[] = $dir . DIRECTORY_SEPARATOR . $file;
           } else if (is_file($dir . DIRECTORY_SEPARATOR . $file)) {
               unlink($dir . DIRECTORY_SEPARATOR . $file);
           } else {
               trigger_error('clear_tmp_dir: ignoring ' . $dir .
                             DIRECTORY_SEPARATOR . $file, E_USER_ERROR);
           }
       }

       if (end($stack) == $dir) {
           rmdir($dir);
           array_pop($stack);
       }
   }
}
lodemessemaker at hotmail dot com
22-Sep-2005 08:13
In reaction to the function rmdirr() by makarenkoa at ukrpost dot net:

If verbose is set to TRUE, it will only work in the first (target) directory, and not in subdirectories. To make the function verbose in subdirectories as well, change the following:

<?php
...
       if(
is_dir($object))
          
rmdirr($object);
...
?>

TO

<?php
...
       if(
is_dir($object))
          
rmdirr($object,$verbose);
?>
dexn (at) metazure.com
03-Aug-2005 08:01
Here's a short function I wrote to remove a directory and all it's contents using the glob() function:

function rmdirr($dir) {
   if($objs = glob($dir."/*")){
       foreach($objs as $obj) {
           is_dir($obj)? rmdirr($obj) : unlink($obj);
       }
   }
   rmdir($dir);
}
makarenkoa at ukrpost dot net
25-Jul-2005 02:07
<?php
// rmdirr.inc.php
/*
25.07.2005
Author: Anton Makarenko
   makarenkoa at ukrpost dot net
   webmaster at eufimb dot edu dot ua
Original idea:
   http://ua2.php.net/manual/en/function.rmdir.php
   28-Apr-2005 07:35
   development at lab-9 dot com
*/
function rmdirr($target,$verbose=false)
// removes a directory and everything within it
{
$exceptions=array('.','..');
if (!
$sourcedir=@opendir($target))
   {
   if (
$verbose)
       echo
'<strong>Couldn&#146;t open '.$target."</strong><br />\n";
   return
false;
   }
while(
false!==($sibling=readdir($sourcedir)))
   {
   if(!
in_array($sibling,$exceptions))
       {
      
$object=str_replace('//','/',$target.'/'.$sibling);
       if(
$verbose)
           echo
'Processing: <strong>'.$object."</strong><br />\n";
       if(
is_dir($object))
          
rmdirr($object);
       if(
is_file($object))
           {
          
$result=@unlink($object);
           if (
$verbose&&$result)
               echo
"File has been removed<br />\n";
           if (
$verbose&&(!$result))
               echo
"<strong>Couldn&#146;t remove file</strong>";
           }
       }
   }
closedir($sourcedir);
if(
$result=@rmdir($target))
   {
   if (
$verbose)
       echo
"Target directory has been removed<br />\n";
   return
true;
   }
if (
$verbose)
   echo
"<strong>Couldn&#146;t remove target directory</strong>";
return
false;
}
/*
// sample usage
<?php
require('./lib/rmdirr.inc.php');
rmdirr('D:/srv/Apache2/htdocs/testRm',true);
?>
//*/
?>
m dot winkel at stonkel dot de
09-Jun-2005 12:44
The example in the previous note will stop and return false, if there is an empty subdirectory. I suggest to modify this snipplet of the previous example:

<?
$matching
= glob($fileglob);
     if (
$matching === false) {
        
trigger_error(sprintf('No files match supplied glob %s', $fileglob), E_USER_WARNING);
         return
false;
     }

?>

Here is my version:

<?
$matching
= glob($fileglob);
     if (
$matching === false) {
         return
true;
     }
?>

If there are no matching files in the directory, there is no need to delete something or to trigger an error. It just returns true and the (empty) directory will be deleted by the rmdir command.
bishop
06-Jun-2005 03:34
<?php
/**
 * rm() -- Vigorously erase files and directories.
 *
 * @param $fileglob mixed If string, must be a file name (foo.txt), glob pattern (*.txt), or directory name.
 *                        If array, must be an array of file names, glob patterns, or directories.
 */
function rm($fileglob)
{
   if (
is_string($fileglob)) {
       if (
is_file($fileglob)) {
           return
unlink($fileglob);
       } else if (
is_dir($fileglob)) {
          
$ok = rm("$fileglob/*");
           if (!
$ok) {
               return
false;
           }
           return
rmdir($fileglob);
       } else {
          
$matching = glob($fileglob);
           if (
$matching === false) {
              
trigger_error(sprintf('No files match supplied glob %s', $fileglob), E_USER_WARNING);
               return
false;
           }     
          
$rcs = array_map('rm', $matching);
           if (
in_array(false, $rcs)) {
               return
false;
           }
       }     
   } else if (
is_array($fileglob)) {
      
$rcs = array_map('rm', $fileglob);
       if (
in_array(false, $rcs)) {
           return
false;
       }
   } else {
      
trigger_error('Param #1 must be filename or glob pattern, or array of filenames or glob patterns', E_USER_ERROR);
       return
false;
   }

   return
true;
}
?>
php at aithal dot org
28-May-2005 11:25
In the previous examples of recursive rmdir, people should take care to use the proper way of calling readdir:

<?

while (false !== ($file = readdir($dir))) {
  
// do some stuff with $file
}

?>

If you don't use this syntax, the loop will halt if it ever comes across a file named '0'.

http://www.php.net/readdir - provides more info on why this is the case.

hth
vittal
development at lab-9 dot com
29-Apr-2005 12:35
Here a small and useful function for removing files by deleting also subdirectories recursive.

this function takes:
$target .. a absolute target path, f.e: /var/www/html/remove_this
$exceptions .. a array of directorynames which don't have to be removed .. usually unused as you want to delete whole directory :-)
$output=true .. outputs a status message of which file or directory the script just has accessed to;

<?php
function delete_files($target, $exceptions, $output=true)
{
  
$sourcedir = opendir($target);
   while(
false !== ($filename = readdir($sourcedir)))
   {
       if(!
in_array($filename, $exceptions))
       {
           if(
$output)
           { echo
"Processing: ".$target."/".$filename."<br>"; }
           if(
is_dir($target."/".$filename))
           {
              
// recurse subdirectory; call of function recursive
              
delete_files($target."/".$filename, $exceptions);
           }
           else if(
is_file($target."/".$filename))
           {
              
// unlink file
              
unlink($target."/".$filename);
           }
       }
   }
  
closedir($sourcedir);
   if(
rmdir($target))
   { return
true; }
   else
   { return
false; }
}
?>

here a example of function call:
<?php
$exceptions
= array(".", "..");
if(
delete_files("/var/www/html/this_dir", $exceptions, true))
{ echo
"deletion successed"; }
else
{ echo
"deletion failed"; }
?>

KNOWN ISSUE:
if you call the function with an exception folder and that folder is a childfolder, this function won't be able to remove the parent directory and returns false .. :-/ .. if someone knows a workaround please email me :-)
czambran at gmail dot com
06-Mar-2005 03:21
A quick note on the function posted by Daniellehr[-at-]gmx[-dot-]de, the function as it is will delete everything inside the directory but the directory. The problem is that the function does not close the directory before executing the rmdir line. Here is the corrected function:
function delDir($dirName) {
   if(empty($dirName)) {
       return true;
   }
   if(file_exists($dirName)) {
       $dir = dir($dirName);
       while($file = $dir->read()) {
           if($file != '.' && $file != '..') {
               if(is_dir($dirName.'/'.$file)) {
                   delDir($dirName.'/'.$file);
               } else {
                   @unlink($dirName.'/'.$file) or die('File '.$dirName.'/'.$file.' couldn\'t be deleted!');
               }
           }
       }
       $dir->close();
       @rmdir($dirName) or die('Folder '.$dirName.' couldn\'t be deleted!');
   } else {
       return false;
   }
   return true;
}
itsdapead
01-Mar-2005 01:03
Warning!  On Unix-type systems, most of the "delete directory tree" functions posted here will follow & delete symbolic links (which is not what you'd expect of, say, rm-rf) so you might find more than you bargained for getting wiped.

Here's a quick kludge of an earlier submission (by tekangel) that avoids this by default.

Make sure it does what you want before you uncomment the unlink and rmdir commands!

<?
function rmdirRecursive($path,$followLinks=false) {
  
  
$dir = opendir($path) ;
   while (
$entry = readdir($dir) ) {
      
       if (
is_file( "$path/$entry" ) || ((!$followLinks) && is_link("$path/$entry")) ) {
           echo (
"unlink $path/$entry;\n" );
          
// Uncomment when happy!
           //unlink( "$path/$entry" );
      
} elseif ( is_dir( "$path/$entry" ) && $entry!='.' && $entry!='..' ) {
          
rmdirRecursive( "$path/$entry" ) ;
       }
   }
  
closedir($dir) ;
   echo
"rmdir $path;\n";
  
// Uncomment when happy!
   // return rmdir($path);
}
?>
Daniellehr[-at-]gmx[-dot-]de
20-Feb-2005 05:55
If you want to delete a folder with its all content and sub-content you can use this recursive-working function
(WARNING: after using the function the folder is completely deleted!):
<?php
function delDir($dirName) {
   if(empty(
$dirName)) {
       return;
   }
   if(
file_exists($dirName)) {
      
$dir = dir($dirName);
       while(
$file = $dir->read()) {
           if(
$file != '.' && $file != '..') {
               if(
is_dir($dirName.'/'.$file)) {
                  
delDir($dirName.'/'.$file);
               } else {
                   @
unlink($dirName.'/'.$file) or die('File '.$dirName.'/'.$file.' couldn\'t be deleted!');
               }
           }
       }
       @
rmdir($dirName.'/'.$file) or die('Folder '.$dirName.'/'.$file.' couldn\'t be deleted!');
   } else {
       echo
'Folder "<b>'.$dirName.'</b>" doesn\'t exist.';
   }
}
?>
aidan at php dot net
05-Sep-2004 03:48
If you want to delete a file, or an entire folder (including the contents), use the below function.

http://aidan.dotgeek.org/lib/?file=function.rmdirr.php