Delete/copy directories recursively using PHP

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.

You may also like...

5 Responses

  1. Blaise says:

    Pretty insightful. Thanks!

  2. qwerty says:

    I want to duplicate folder public_html
    can u help

    • Hi there qwerty,
      you mean you want to copy public_html from one location to another? In this case you can simply use the function copyDirectory provided above. Or am I missing something here?

  3. Sean says:

    Thanks for the code snippet; it works great. Just a couple comments for anyone that comes across the article or for editing:

    Line 27 of copyDirectory
    self::copyDirectoy($source . ‘/’ . $file, $dest . ‘/’ . $file, $excludeSvnFolders);

    should be
    self::copyDirectory($source . ‘/’ . $file, $dest . ‘/’ . $file, $excludeSvnFolders);

    Line 25 of copyDirectory
    mkdir($dest . ‘/’ . $file, 755);

    should be
    mkdir($dest . ‘/’ . $file, 0755);
    The mode always begins with a 0

    Thanks again, this was very useful!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.