copy

(PHP 3, PHP 4, PHP 5)

copy -- 拷贝文件

说明

bool copy ( string source, string dest )

将文件从 source 拷贝到 dest。如果成功则返回 TRUE,失败则返回 FALSE

例子 1. copy() 例子

<?php
$file
= 'example.txt';
$newfile = 'example.txt.bak';

if (!
copy($file, $newfile)) {
    echo
"failed to copy $file...\n";
}
?>

如果要移动文件的话,请使用 rename() 函数。

注: 从 PHP 4.3.0 开始,如果启用了“fopen wrappers”的话,sourcedest 都可以是 URL。更多细节见 fopen()。如果 dest 是一个 URL,则如果封装协议不支持覆盖已有的文件时拷贝操作会失败。

警告

如果目标文件已存在,将会被覆盖。

Windows 兼容: 如果复制一个零字节的文件,copy() 将返回 FALSE ,但文件也会被正确复制。

参见 move_uploaded_file()rename() 和手册中关于文件上传处理一节。


add a note add a note User Contributed Notes
SkyEye
08-Oct-2006 10:21
<?php

// A function to copy files from one directory to another one, including subdirectories and
// nonexisting or newer files. Function returns number of files copied.
// This function is PHP implementation of Windows xcopy  A:\dir1\* B:\dir2 /D /E /F /H /R /Y
// Syntaxis: [$number =] dircopy($sourcedirectory, $destinationdirectory [, $verbose]);
// Example: $num = dircopy('A:\dir1', 'B:\dir2', 1);

function dircopy($srcdir, $dstdir, $verbose = false) {
 
$num = 0;
  if(!
is_dir($dstdir)) mkdir($dstdir);
  if(
$curdir = opendir($srcdir)) {
   while(
$file = readdir($curdir)) {
     if(
$file != '.' && $file != '..') {
      
$srcfile = $srcdir . '\\' . $file;
      
$dstfile = $dstdir . '\\' . $file;
       if(
is_file($srcfile)) {
         if(
is_file($dstfile)) $ow = filemtime($srcfile) - filemtime($dstfile); else $ow = 1;
         if(
$ow > 0) {
           if(
$verbose) echo "Copying '$srcfile' to '$dstfile'...";
           if(
copy($srcfile, $dstfile)) {
            
touch($dstfile, filemtime($srcfile)); $num++;
             if(
$verbose) echo "OK\n";
           }
           else echo
"Error: File '$srcfile' could not be copied!\n";
         }                 
       }
       else if(
is_dir($srcfile)) {
        
$num += dircopy($srcfile, $dstfile, $verbose);
       }
     }
   }
  
closedir($curdir);
  }
  return
$num;
}

?>
fred dot haab at gmail dot com
19-Aug-2006 08:49
Just some caveats for people to consider when working with this copy function.  Like everyone else, I needed a recursive copy function, so I wrote one.

It worked great until I hit a file greater than 2GB, at which point I got a File Size Exceeded error.  I've read that you can recompile PHP with larger file support, but I'm not able to do this on my system.

So I used exec to copy one file at a time (I need to do other things to the file, so can't just do an exec with "cp -r").  Then I ran into problems with spaces in the names.  The escapeshellcmd and escapeshellargs functions don't seem to cleanup spaces, so I wrote my own function to do that.
denis at i39 dot ru
10-Aug-2006 08:53
You can also try to copy with:
<?
exec
("cp -r /var/www/mysite /var/backup");
?>
SBoisvert at Don'tSpamMe dot Bryxal dot ca
25-Jul-2006 04:38
to the editor's: Please pardon me.... remove my other 2 messages and this little comment and just stick this.

just a quick note to add to the great function by:bobbfwed at comcast dot net

this little version has the path not in a define but as a function parameter and also creates the destination directory if it is not already created.

<?php

 
// copy a directory and all subdirectories and files (recursive)
  // void dircpy( str 'source directory', str 'destination directory' [, bool 'overwrite existing files'] )
function dircpy($basePath, $source, $dest, $overwrite = false){
   if(!
is_dir($basePath . $dest)) //Lets just make sure our new folder is already created. Alright so its not efficient to check each time... bite me
  
mkdir($basePath . $dest);
   if(
$handle = opendir($basePath . $source)){        // if the folder exploration is sucsessful, continue
      
while(false !== ($file = readdir($handle))){ // as long as storing the next file to $file is successful, continue
          
if($file != '.' && $file != '..'){
              
$path = $source . '/' . $file;
               if(
is_file($basePath . $path)){
                   if(!
is_file($basePath . $dest . '/' . $file) || $overwrite)
                   if(!@
copy($basePath . $path, $basePath . $dest . '/' . $file)){
                       echo
'<font color="red">File ('.$path.') could not be copied, likely a permissions problem.</font>';
                   }
               } elseif(
is_dir($basePath . $path)){
                   if(!
is_dir($basePath . $dest . '/' . $file))
                  
mkdir($basePath . $dest . '/' . $file); // make subdirectory before subdirectory is copied
                  
dircpy($basePath, $path, $dest . '/' . $file, $overwrite); //recurse!
              
}
           }
       }
      
closedir($handle);
   }
}

?>
emielm at hotmail dot com
09-Jul-2006 03:49
I have been puzzling for hours with the copy() function. I got a "no such file or directory" error message all the time (for the source file). In the end my mistake was that there were some spaces at the end of de source filename...

So, if you get file not found errors and you are sure that the file does exists, use the trim() function to get rid of the spaces.
cooper at asu dot ntu-kpi dot kiev dot ua
10-Mar-2006 08:32
It take me a long time to find out what the problem is when i've got an error on copy(). It DOESN'T create any directories. It only copies to existing path. So create directories before. Hope i'll help,
bobbfwed at comcast dot net
03-Feb-2006 03:06
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.
I know there are others like it, but here is the function I made for this program to copy directories; 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);

 
// copy a directory and all subdirectories and files (recursive)
  // void dircpy( str 'source directory', str 'destination directory' [, bool 'overwrite existing files'] )
function dircpy($source, $dest, $overwrite = false){

  if(
$handle = opendir(loc1 . $source)){        // if the folder exploration is sucsessful, continue
  
while(false !== ($file = readdir($handle))){ // as long as storing the next file to $file is successful, continue
    
if($file != '.' && $file != '..'){
      
$path = $source . '/' . $file;
       if(
is_file(loc1 . $path)){
         if(!
is_file(loc1 . $dest . '/' . $file) || $overwrite)
           if(!@
copy(loc1 . $path, loc1 . $dest . '/' . $file)){
             echo
'<font color="red">File ('.$path.') could not be copied, likely a permissions problem.</font>';
           }
       } elseif(
is_dir(loc1 . $path)){
         if(!
is_dir(loc1 . $dest . '/' . $file))
          
mkdir(loc1 . $dest . '/' . $file); // make subdirectory before subdirectory is copied
        
dircpy($path, $dest . '/' . $file, $overwrite); //recurse!
      
}
     }
   }
  
closedir($handle);
  }
}
// end of dircpy()
?>

This new function will be in 0.9.7 (the current release of File Manage) which has just been released 2/2/06.
Hope this helps some people.
makarenkoa at ukrpost dot net
26-Jul-2005 07:58
A function that copies contents of source directory to destination directory and sets up file modes.
It may be handy to install the whole site on hosting.
<?php
// copydirr.inc.php
/*
26.07.2005
Author: Anton Makarenko
   makarenkoa at ukrpost dot net
   webmaster at eufimb dot edu dot ua
*/
function copydirr($fromDir,$toDir,$chmod=0757,$verbose=false)
/*
   copies everything from directory $fromDir to directory $toDir
   and sets up files mode $chmod
*/
{
//* Check for some errors
$errors=array();
$messages=array();
if (!
is_writable($toDir))
  
$errors[]='target '.$toDir.' is not writable';
if (!
is_dir($toDir))
  
$errors[]='target '.$toDir.' is not a directory';
if (!
is_dir($fromDir))
  
$errors[]='source '.$fromDir.' is not a directory';
if (!empty(
$errors))
   {
   if (
$verbose)
       foreach(
$errors as $err)
           echo
'<strong>Error</strong>: '.$err.'<br />';
   return
false;
   }
//*/
$exceptions=array('.','..');
//* Processing
$handle=opendir($fromDir);
while (
false!==($item=readdir($handle)))
   if (!
in_array($item,$exceptions))
       {
      
//* cleanup for trailing slashes in directories destinations
      
$from=str_replace('//','/',$fromDir.'/'.$item);
      
$to=str_replace('//','/',$toDir.'/'.$item);
      
//*/
      
if (is_file($from))
           {
           if (@
copy($from,$to))
               {
              
chmod($to,$chmod);
              
touch($to,filemtime($from)); // to track last modified time
              
$messages[]='File copied from '.$from.' to '.$to;
               }
           else
              
$errors[]='cannot copy file from '.$from.' to '.$to;
           }
       if (
is_dir($from))
           {
           if (@
mkdir($to))
               {
              
chmod($to,$chmod);
              
$messages[]='Directory created: '.$to;
               }
           else
              
$errors[]='cannot create directory '.$to;
          
copydirr($from,$to,$chmod,$verbose);
           }
       }
closedir($handle);
//*/
//* Output
if ($verbose)
   {
   foreach(
$errors as $err)
       echo
'<strong>Error</strong>: '.$err.'<br />';
   foreach(
$messages as $msg)
       echo
$msg.'<br />';
   }
//*/
return true;
}
/* sample usage:
WARNING:
if You set wrong $chmod then You'll not be able to access files and directories
in destination directory.
For example: once upon a time I've called the function with parameters:
copydir($fromDir,$toDir,true);
What happened? I've forgotten one parameter (chmod)
What happened next? Those files and directories became inaccessible for me
(they had mode 0001), so I had to ask sysadmin to delete them from root account
Be careful :-)
<?php
require('./copydirr.inc.php');
copydirr('./testSRC','D:/srv/Apache2/htdocs/testDEST',0777,true);
?>
*/
?>
Andrzej Nadziejko (andrzej at vao . pl)
27-Jun-2005 03:52
These functions are to copy and remove big directories:

/*
source files are in source directory
*/
function SetupFolder($dir_name)
{
   mkdir($dir_name,'0777');
   $folder = opendir('source');
   while($file = readdir($folder))
   {   
       if ($file == '.' || $file == '..') {
           continue;
       }
       if(is_dir('source/'.$file))
       {
           mkdir($dir_name.'/'.$file,0777);
           CopyFiles('source/'.$file,$dir_name.'/'.$file);
       }
       else
       {   
           copy('source/'.$file,$dir_name.'/'.$file);
       }
   }
   closedir($folder);
   return 1;
}
//copy many files
function CopyFiles($source,$dest)
{   
   $folder = opendir($source);
   while($file = readdir($folder))
   {
       if ($file == '.' || $file == '..') {
           continue;
       }
      
       if(is_dir($source.'/'.$file))
       {
           mkdir($dest.'/'.$file,0777);
           CopySourceFiles($source.'/'.$file,$dest.'/'.$file);
       }
       else
       {
           copy($source.'/'.$file,$dest.'/'.$file);
       }
      
   }
   closedir($folder);
   return 1;
}
//remove file, directories, subdirectories
function RemoveFiles($source)
{
   $folder = opendir($source);
   while($file = readdir($folder))
   {
       if ($file == '.' || $file == '..') {
           continue;
       }
      
       if(is_dir($source.'/'.$file))
       {
           RemoveFiles($source.'/'.$file);
       }
       else
       {
           unlink($source.'/'.$file);
       }
      
   }
   closedir($folder);
   rmdir($source);
   return 1;
}
info at sameprecision dot org
29-Jan-2005 07:54
When using copy on win32 (don't know about anywhere else),  copy sets the 'last modified time' of the the new copy to the current time instead of that of the source (win32 copy preserves last modified time).  If you are tracking backups by last modified time, use:

<?php

copy
($src, $dest); touch($dest, filemtime($src));

?>
20-Jan-2005 08:34
Heres a quick function I wrote to backup whole websites.
I haven't actually tested it out yet. I will later on  =P
<?

function backup($extension) {
  
$counter = 0;
   foreach(
glob(* . $extension) as $file) {
       if (
$extension{0} != .) {
          
$extension = . . $extension;
       }
      
$file2 = ./backup/ . $file;
      
$counter++;
      
copy($file, $file2);
   }
   if (
$counter == 0) {
       return
false;
   } else {
       return
true;
   }
}

/* Test -- Copy all images */

$extension_array = array(.jpg, .gif, .png, .bmp);

foreach(
$extension_array as $key => $value) {
  
backup($extension);
}

?>
simonr_at_orangutan_dot_co_dot_uk
03-Sep-2004 04:54
Having spent hours tacking down a copy() error: Permission denied , (and duly worrying about chmod on winXP) , its worth pointing out that the 'destination' needs to contain the actual file name ! --- NOT just the path to the folder you wish to copy into.......
DOH !
hope this saves somebody hours of fruitless debugging
aidan at php dot net
30-Aug-2004 03:29
If you want to copy a file, or an entire folder (including the contents), use the below function.

http://aidan.dotgeek.org/lib/?file=function.copyr.php
kadnan at yahoo dot com
30-Aug-2004 01:30
you can also try xcopy command by using Shell to move/copy files/folders from one place to another
here is the code:

<?php
exec
('xcopy c:\\myfolder d:\\myfolder /e/i', $a, $a1);
?>

by executing this command, it will move folder along with all contents to destination.

-adnan