Posted on 6 Comments

Delete/copy directories recursively using PHP

PHP Logo

As there currently does not exist a PHP function that allows developers to delete or copy entire (non-empty) directories at once one has to recursively loop through them to manually delete/copy their contents.

This post provides you with two easy to use functions for

  1. deleting entire (non-empty) directories
  2. copying entire (non-empty) directories

First, let’s start with the delete function:

/**
  * Removes all files from $source, optionally ignoring SVN meta-data 
  * folders (default).
  * @param string $source
  * @return boolean 
  */
public static function deleteDirectory($source, $excludeSvnFolders=true, $recusion=false) {
  $dir_handle = opendir($source);

  if (!$dir_handle)
    return false;

  while ($file = readdir($dir_handle)) {
    if ($file == '.' || $file == '..')
      continue;
    if ($excludeSvnFolders && $file == '.svn')
      continue;

    if (!is_dir($source . '/' . $file)) {
      unlink($source . '/' . $file);
    } else {
      self::deleteDirectory($source . '/' . $file, $excludeSvnFolders, true);
    }
  }

  closedir($dir_handle);

  if ($recusion) {
    rmdir($source);
  }

  return true;
}

The second function handles copying entire directories:

/**
 * Copies contents from $source to $dest, optionally ignoring SVN meta-data
 * folders (default).
 * @param string $source
 * @param string $dest
 * @param boolean $ignoreSvnFolders
 * @return boolean true on success false otherwise
 */
public static function copyDirectory($source, $dest, $excludeSvnFolders=true) {
  $sourceHandle = opendir($source);

  if (!$sourceHandle) {
     echo 'failed to copy directory: failed to open source ' . $source;
     return false;
  }

  while ($file = readdir($sourceHandle)) {
    if ($file == '.' || $file == '..')
      continue;
    if ($excludeSvnFolders && $file == '.svn')
      continue;

    if (is_dir($source . '/' . $file)) {
      if (!file_exists($dest . '/' . $file)) {
        mkdir($dest . '/' . $file, 0755);
      }
      self::copyDirectory($source . '/' . $file, $dest . '/' . $file, $excludeSvnFolders);
    } else {
      copy($source . '/' . $file, $dest . '/' . $file);
    }
  }
  
  return true;
}

As you may have noticed both function are declared static. This is due to the fact that I am using them in a general purpose file management class.

Both functions offer the possibility to ignore SVN meta-data folders, i.e. .svn directories. Further improvements to these functions could be to extend them with an array of folders and files to exclude, instead of the boolean $excludeSvnFolders.