Saya mencoba menyalin seluruh isi direktori ke lokasi lain menggunakan
copy ("old_location/*.*","new_location/");
tetapi dikatakan tidak dapat menemukan aliran, benar *.*
tidak ditemukan.
Cara lain
Terima kasih Dave
Jawaban:
Tampaknya salinan hanya menangani file tunggal . Berikut adalah fungsi untuk menyalin secara rekursif yang saya temukan dalam catatan ini di halaman
dokumentasi salinan :
php
function recurse_copy($src,$dst) {
$dir = opendir($src);
@mkdir($dst);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
recurse_copy($src . '/' . $file,$dst . '/' . $file);
}
else {
copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
}
?>
Seperti dijelaskan di sini , ini adalah pendekatan lain yang menangani symlink juga:
/**
* Copy a file, or recursively copy a folder and its contents
* @author Aidan Lister <>
* @version 1.0.1
* @link http://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));
}
copy () hanya
berfungsi dengan file.
Baik perintah salin DOS dan Unix cp akan menyalin secara rekursif - jadi solusi tercepat adalah dengan keluar dan menggunakannya. misalnya
`cp -r $src $dest`;
Kalau tidak, Anda harus menggunakan opendir
/readdir
atau scandir
untuk membaca isi direktori, beralih melalui hasilnya dan jika is_dir mengembalikan true untuk masing-masing, kembalilah ke dalamnya.
misalnya
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);
}
}
}
Solusi
terbaik adalah!
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 "Copy Paste completed!
"; //output when done
?>
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 );
}
}
Seperti yang dikatakan di tempat lain, copy
hanya bekerja dengan satu file untuk sumber dan bukan pola. Jika Anda ingin menyalin berdasarkan pola, gunakan glob
untuk menentukan file, kemudian jalankan salin. Ini tidak akan menyalin subdirektori, juga tidak akan membuat
direktori tujuan.
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 files
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 );
}
}
?>
dari baris 4 terakhir, buat ini
$source = 'wordpress';//i.e. your source path
dan
$destination ='b';
Terima kasih penuh harus ditujukan kepada Felix Kling untuk jawaban luar biasa yang telah saya gunakan dengan penuh syukur dalam kode saya. Saya menawarkan peningkatan kecil dari nilai pengembalian boolean untuk melaporkan keberhasilan atau
kegagalan:
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;
}
Versi @Kzoty saya yang sudah dipangkas. Terima kasih, Kzoty.
Pemakaian
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();
}
}
Saya mengkloning seluruh direktori dengan 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");
// using exec
function rCopy($directory, $destination)
{
$command = sprintf('cp -r %s/* %s', $directory, $destination);
exec($command);
}
Untuk server Linux, Anda hanya perlu satu baris kode untuk menyalin secara rekursif sambil mempertahankan izin:
exec('cp -a '.$source.' '.$dest);
Cara lain untuk melakukannya adalah:
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());
}
tapi lebih lambat dan tidak mempertahankan izin.
Saya memiliki situasi yang serupa di mana saya perlu menyalin dari satu domain ke domain lain di server yang sama, Inilah yang berhasil dalam kasus saya, Anda juga
dapat menyesuaikan sesuai keinginan Anda:
foreach(glob('../folder/*.php') as $file) {
$adjust = substr($file,3);
copy($file, '/home/user/abcde.com/'.$adjust);
Perhatikan penggunaan "substr ()", tanpa itu, tujuan menjadi '/ home / pengguna / abcde.com/../folder/', yang mungkin sesuatu yang tidak Anda inginkan. Jadi, saya menggunakan substr () untuk menghilangkan 3 karakter pertama (../) untuk mendapatkan tujuan yang diinginkan yaitu '/home/user/abcde.com/folder/'. Jadi, Anda dapat menyesuaikan fungsi substr () dan juga fungsi glob () hingga sesuai dengan kebutuhan pribadi Anda. Semoga ini
membantu.