I tried to copy the entire contents of the directory to another location using
copy ("old_location/*.*","new_location/");but it says it cannot find stream, true *.* is not found.
Any other way
Thanks Dave
Asaph
156k25 gold badges190 silver badges194 bronze badges
asked Jan 12, 2010 at 17:17
5
that worked for a one level directory. for a folder with multi-level directories I used this:
function recurseCopy( string $sourceDirectory, string $destinationDirectory, string $childFolder = '' ): void { $directory = opendir($sourceDirectory); if (is_dir($destinationDirectory) === false) { mkdir($destinationDirectory); } if ($childFolder !== '') { if (is_dir("$destinationDirectory/$childFolder") === false) { mkdir("$destinationDirectory/$childFolder"); } while (($file = readdir($directory)) !== false) { if ($file === '.' || $file === '..') { continue; } if (is_dir("$sourceDirectory/$file") === true) { recurseCopy("$sourceDirectory/$file", "$destinationDirectory/$childFolder/$file"); } else { copy("$sourceDirectory/$file", "$destinationDirectory/$childFolder/$file"); } } closedir($directory); return; } while (($file = readdir($directory)) !== false) { if ($file === '.' || $file === '..') { continue; } if (is_dir("$sourceDirectory/$file") === true) { recurseCopy("$sourceDirectory/$file", "$destinationDirectory/$file"); } else { copy("$sourceDirectory/$file", "$destinationDirectory/$file"); } } closedir($directory); }
Max
3551 gold badge3 silver badges10 bronze badges
answered Jan 12, 2010 at 17:23
Felix KlingFelix Kling
769k171 gold badges1068 silver badges1114 bronze badges
9
As described here, this is another approach that takes care of symlinks too:
/** * Copy a file, or recursively copy a folder and its contents * @author Aidan Lister <> * @version 1.0.1 * @link //aidanlister.com/2004/04/recursively-copying-directories-in-php/ * @param string $source Source path * @param string $dest Destination path * @param int $permissions New folder creation permissions * @return bool Returns true on success, false on failure */ function xcopy($source, $dest, $permissions = 0755) { $sourceHash = hashDirectory($source); // Check for symlinks if (is_link($source)) { return symlink(readlink($source), $dest); } // Simple copy for a file if (is_file($source)) { return copy($source, $dest); } // Make destination directory if (!is_dir($dest)) { mkdir($dest, $permissions); } // Loop through the folder $dir = dir($source); while (false !== $entry = $dir->read()) { // Skip pointers if ($entry == '.' || $entry == '..') { continue; } // Deep copy directories if($sourceHash != hashDirectory($source."/".$entry)){ xcopy("$source/$entry", "$dest/$entry", $permissions); } } // Clean up $dir->close(); return true; } // In case of coping a directory inside itself, there is a need to hash check the directory otherwise and infinite loop of coping is generated function hashDirectory($directory){ if (! is_dir($directory)){ return false; } $files = array(); $dir = dir($directory); while (false !== ($file = $dir->read())){ if ($file != '.' and $file != '..') { if (is_dir($directory . '/' . $file)) { $files[] = hashDirectory($directory . '/' . $file); } else { $files[] = md5_file($directory . '/' . $file); } } } $dir->close(); return md5(implode('', $files)); }
answered Oct 6, 2012 at 21:17
itsjaviitsjavi
2,5762 gold badges20 silver badges24 bronze badges
3
copy() only works with files.
Both the DOS copy and Unix cp commands will copy recursively - so the quickest solution is just to shell out and use these. e.g.
`cp -r $src $dest`;Otherwise you'll need to use the opendir/readdir or scandir to read the contents of the directory, iterate through the results and if is_dir returns true for each one, recurse into it.
e.g.
function xcopy($src, $dest) { foreach (scandir($src) as $file) { if (!is_readable($src . '/' . $file)) continue; if (is_dir($src .'/' . $file) && ($file != '.') && ($file != '..') ) { mkdir($dest . '/' . $file); xcopy($src . '/' . $file, $dest . '/' . $file); } else { copy($src . '/' . $file, $dest . '/' . $file); } } }answered Jan 12, 2010 at 17:32
symcbeansymcbean
46.9k6 gold badges56 silver badges90 bronze badges
2
The best solution is!
<?php $src = "/home/www/domain-name.com/source/folders/123456"; $dest = "/home/www/domain-name.com/test/123456"; shell_exec("cp -r $src $dest"); echo "<H3>Copy Paste completed!</H3>"; //output when done ?>
bstpierre
28.9k14 gold badges67 silver badges102 bronze badges
answered Apr 21, 2011 at 0:28
blackblack
3453 silver badges2 bronze badges
7
function full_copy( $source, $target ) { if ( is_dir( $source ) ) { @mkdir( $target ); $d = dir( $source ); while ( FALSE !== ( $entry = $d->read() ) ) { if ( $entry == '.' || $entry == '..' ) { continue; } $Entry = $source . '/' . $entry; if ( is_dir( $Entry ) ) { full_copy( $Entry, $target . '/' . $entry ); continue; } copy( $Entry, $target . '/' . $entry ); } $d->close(); }else { copy( $source, $target ); } }
Mr.Wizard
24k5 gold badges42 silver badges120 bronze badges
answered Apr 29, 2011 at 15:47
kzotykzoty
1711 silver badge2 bronze badges
1
Like said elsewhere, copy only works with a single file for source and not a pattern. If you want to copy by pattern, use glob to determine the files, then run copy. This will not copy subdirectories though, nor will it create the destination directory.
function copyToDir($pattern, $dir) { foreach (glob($pattern) as $file) { if(!is_dir($file) && is_readable($file)) { $dest = realpath($dir . DIRECTORY_SEPARATOR) . basename($file); copy($file, $dest); } } } copyToDir('./test/foo/*.txt', './test/bar'); // copies all txt filesanswered Jan 12, 2010 at 18:10
GordonGordon
307k72 gold badges526 silver badges551 bronze badges
1
<?php function copy_directory( $source, $destination ) { if ( is_dir( $source ) ) { @mkdir( $destination ); $directory = dir( $source ); while ( FALSE !== ( $readdirectory = $directory->read() ) ) { if ( $readdirectory == '.' || $readdirectory == '..' ) { continue; } $PathDir = $source . '/' . $readdirectory; if ( is_dir( $PathDir ) ) { copy_directory( $PathDir, $destination . '/' . $readdirectory ); continue; } copy( $PathDir, $destination . '/' . $readdirectory ); } $directory->close(); }else { copy( $source, $destination ); } } ?>
from the last 4th line , make this
$source = 'wordpress';//i.e. your source pathand
$destination ='b';
Guern
1,1891 gold badge11 silver badges30 bronze badges
answered Mar 6, 2013 at 20:40
0
Full thanks must go to Felix Kling for his excellent answer which I have gratefully used in my code. I offer a small enhancement of a boolean return value to report success or failure:
function recurse_copy($src, $dst) { $dir = opendir($src); $result = ($dir === false ? false : true); if ($result !== false) { $result = @mkdir($dst); if ($result === true) { while(false !== ( $file = readdir($dir)) ) { if (( $file != '.' ) && ( $file != '..' ) && $result) { if ( is_dir($src . '/' . $file) ) { $result = recurse_copy($src . '/' . $file,$dst . '/' . $file); } else { $result = copy($src . '/' . $file,$dst . '/' . $file); } } } closedir($dir); } } return $result; }
answered Jan 4, 2013 at 11:23
gonzogonzo
5186 silver badges6 bronze badges
2
My pruned version of @Kzoty answer. Thank you Kzoty.
Usage
Helper::copy($sourcePath, $targetPath); class Helper { static function copy($source, $target) { if (!is_dir($source)) {//it is a file, do a normal copy copy($source, $target); return; } //it is a folder, copy its files & sub-folders @mkdir($target); $d = dir($source); $navFolders = array('.', '..'); while (false !== ($fileEntry=$d->read() )) {//copy one by one //skip if it is navigation folder . or .. if (in_array($fileEntry, $navFolders) ) { continue; } //do copy $s = "$source/$fileEntry"; $t = "$target/$fileEntry"; self::copy($s, $t); } $d->close(); } }answered Dec 10, 2011 at 19:59
Nam G VUNam G VU
31.5k67 gold badges219 silver badges356 bronze badges
I clone entire directory by SPL Directory Iterator.
function recursiveCopy($source, $destination) { if (!file_exists($destination)) { mkdir($destination); } $splFileInfoArr = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST); foreach ($splFileInfoArr as $fullPath => $splFileinfo) { //skip . .. if (in_array($splFileinfo->getBasename(), [".", ".."])) { continue; } //get relative path of source file or folder $path = str_replace($source, "", $splFileinfo->getPathname()); if ($splFileinfo->isDir()) { mkdir($destination . "/" . $path); } else { copy($fullPath, $destination . "/" . $path); } } } #calling the function recursiveCopy(__DIR__ . "/source", __DIR__ . "/destination");answered Jan 11, 2018 at 12:36
For Linux servers you just need one line of code to copy recursively while preserving permission:
exec('cp -a '.$source.' '.$dest);Another way of doing it is:
mkdir($dest); foreach ($iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($source, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST) as $item) { if ($item->isDir()) mkdir($dest.DIRECTORY_SEPARATOR.$iterator->getSubPathName()); else copy($item, $dest.DIRECTORY_SEPARATOR.$iterator->getSubPathName()); }but it's slower and does not preserve permissions.
answered Oct 24, 2018 at 19:00
Dan BrayDan Bray
6,7603 gold badges49 silver badges64 bronze badges
I had a similar situation where I needed to copy from one domain to another on the same server, Here is exactly what worked in my case, you can as well adjust to suit yours:
foreach(glob('../folder/*.php') as $file) { $adjust = substr($file,3); copy($file, '/home/user/abcde.com/'.$adjust);Notice the use of "substr()", without it, the destination becomes '/home/user/abcde.com/../folder/', which might be something you don't want. So, I used substr() to eliminate the first 3 characters(../) in order to get the desired destination which is '/home/user/abcde.com/folder/'. So, you can adjust the substr() function and also the glob() function until it fits your personal needs. Hope this helps.
answered Apr 27, 2020 at 23:52
ChimdiChimdi
1571 silver badge7 bronze badges
Long-winded, commented example with return logging, based on parts of most of the answers here:
It is presented as a static class method, but could work as a simple function also:
/** * Recursive copy directories and content * * @link //stackoverflow.com/a/2050909/591486 * @since 4.7.2 */ public static function copy_recursive( $source = null, $destination = null, &$log = [] ) { // is directory ## if ( is_dir( $source ) ) { $log[] = 'is_dir: '.$source; // log results of mkdir call ## $log[] = '@mkdir( "'.$destination.'" ): '.@mkdir( $destination ); // get source directory contents ## $source_directory = dir( $source ); // loop over items in source directory ## while ( FALSE !== ( $entry = $source_directory->read() ) ) { // skip hidden ## if ( $entry == '.' || $entry == '..' ) { $log[] = 'skip hidden entry: '.$entry; continue; } // get full source "entry" path ## $source_entry = $source . '/' . $entry; // recurse for directories ## if ( is_dir( $source_entry ) ) { $log[] = 'is_dir: '.$source_entry; // return to self, with new arguments ## self::copy_recursive( $source_entry, $destination.'/'.$entry, $log ); // break out of loop, to stop processing ## continue; } $log[] = 'copy: "'.$source_entry.'" --> "'.$destination.'/'.$entry.'"'; // copy single files ## copy( $source_entry, $destination.'/'.$entry ); } // close connection ## $source_directory->close(); } else { $log[] = 'copy: "'.$source.'" --> "'.$destination.'"'; // plain copy, as $destination is a file ## copy( $source, $destination ); } // clean up log ## $log = array_unique( $log ); // kick back log for debugging ## return $log; }Call like:
// call method ## $log = \namespace\to\method::copy_recursive( $source, $destination ); // write log to error file - you can also just dump it on the screen ## error_log( var_export( $log, true ) );answered Sep 10, 2020 at 8:49
Q StudioQ Studio
1,7763 gold badges15 silver badges17 bronze badges
// using exec function rCopy($directory, $destination) { $command = sprintf('cp -r %s/* %s', $directory, $destination); exec($command); }
answered Jul 11, 2018 at 7:56
For copy entire contents from a directory to another, first you should sure about transfer files that they were transfer correctly. for this reason, we use copy files one by one! in correct directories. we copy a file and check it if true go to next file and continue...
1- I check the safe process of transferring each file with this function:
function checksum($src,$dest) { if(file_exists($src) and file_exists($dest)){ return md5_file($src) == md5_file($dest) ? true : false; }else{ return false; } }2- Now i copy files one by one from src into dest, check it and then continue. (For separate the folders that i don't want to copy them, use exclude array)
$src = __DIR__ . '/src'; $dest = __DIR__ . '/dest'; $exclude = ['.', '..']; function copyDir($src, $dest, $exclude) { !is_dir($dest) ? mkdir($dest) : ''; foreach (scandir($src) as $item) { $srcPath = $src . '/' . $item; $destPath = $dest . '/' . $item; if (!in_array($item, $exclude)) { if (is_dir($srcPath)) { copyDir($srcPath, $destPath, $exclude); } else { copy($srcPath, $destPath); if (checksum($srcPath, $destPath)) { echo 'Success transfer for:' . $srcPath . '<br>'; }else{ echo 'Failed transfer for:' . $srcPath . '<br>'; } } } } }answered Jun 20, 2021 at 5:46
1
I find this to be way simpler, more easily customizable, and to not require any dependency:
foreach(glob("old_location/*") as $file) { copy($file, "new_location/" . basename($file)); }answered Aug 18 at 18:19
Vic SeedoubleyewVic Seedoubleyew
9,9496 gold badges50 silver badges71 bronze badges