Same name and namespace in other branches
  1. 4.7.x includes/file.inc \file_copy()
  2. 5.x includes/file.inc \file_copy()
  3. 6.x includes/file.inc \file_copy()
  4. 7.x includes/file.inc \file_copy()
  5. 8.9.x core/modules/file/file.module \file_copy()
  6. 9 core/modules/file/file.module \file_copy()

Copies a file to a new location. This is a powerful function that in many ways performs like an advanced version of copy().

  • Checks if $source and $dest are valid and readable/writable.
  • Performs a file copy if $source is not equal to $dest.
  • If file already exists in $dest either the call will error out, replace the file or rename the file based on the $replace parameter.

Parameters

$source A string specifying the file location of the original file.: This parameter will contain the resulting destination filename in case of success.

$dest A string containing the directory $source should be copied to.:

$replace Replace behavior when the destination file already exists.:

Return value

True for success, false for failure.

Related topics

File

includes/file.inc, line 228
API for handling file uploads and server file management.

Code

function file_copy(&$source, $dest = 0, $replace = FILE_EXISTS_RENAME) {
  $dest = file_create_path($dest);
  $directory = $dest;
  $basename = file_check_path($directory);

  // Make sure we at least have a valid directory.
  if ($basename === false) {
    drupal_set_message(t('File copy failed: no directory configured, or it could not be accessed.'), 'error');
    return 0;
  }

  // Process a file upload object.
  if (is_object($source)) {
    $file = $source;
    $source = $file->filepath;
    if (!$basename) {
      $basename = $file->filename;
    }
  }
  $source = realpath($source);
  if (!file_exists($source)) {
    drupal_set_message(t('File copy failed: source file does not exist.'), 'error');
    return 0;
  }

  // If destination file is not specified then use filename of source file.
  $basename = $basename ? $basename : basename($source);
  $dest = $directory . '/' . $basename;

  // Make sure source and destination filenames are not the same, makes no sense
  // to copy it if they are. In fact copying the file will most likely result in
  // a 0 byte file. Which is bad. Real bad.
  if ($source != realpath($dest)) {
    if (file_exists($dest)) {
      switch ($replace) {
        case FILE_EXISTS_RENAME:

          // Destination file already exists and we can't replace is so we try and
          // and find a new filename.
          if ($pos = strrpos($basename, '.')) {
            $name = substr($basename, 0, $pos);
            $ext = substr($basename, $pos);
          }
          else {
            $name = $basename;
          }
          $counter = 0;
          do {
            $dest = $directory . '/' . $name . '_' . $counter++ . $ext;
          } while (file_exists($dest));
          break;
        case FILE_EXISTS_ERROR:
          drupal_set_message(t('File copy failed. File already exists.'), 'error');
          return 0;
        case FILE_EXISTS_REPLACE:
      }
    }
    if (!@copy($source, $dest)) {
      drupal_set_message(t('File copy failed.'), 'error');
      return 0;
    }
  }
  if (is_object($file)) {
    $file->filename = $basename;
    $file->filepath = $dest;
    $source = $file;
  }
  else {
    $source = $dest;
  }
  return 1;

  // Everything went ok.
}