পিএইচপি ব্যবহার করে কোনও ডিরেক্টরিতে সম্পূর্ণ সামগ্রীর অনুলিপি করুন


146

আমি ডিরেক্টরিটি সম্পূর্ণ সামগ্রীর অনুলিপি ব্যবহার করে অন্য স্থানে অনুলিপি করার চেষ্টা করেছি

copy ("old_location/*.*","new_location/");

তবে এটি বলে যে এটি স্রোত খুঁজে পায় না, সত্য খুঁজে *.*পাওয়া যায় না।

অন্য কোন উপায়

ধন্যবাদ ডেভ


1
@ সম্পাদক: আপনি কি নিশ্চিত যে "old_location/."এটি কেবল একটি টাইপো ছিল?
ফেলিক্স ক্লিং

ধনী রডেকারের ব্লগে একটি স্ক্রিপ্ট রয়েছে যা কেবল এটি করে। দৃশ্যমান
জন এফ হ্যানকক

@ ফেলিক্স: আমিও একই জিনিসটি ভাবছিলাম। আমি প্রথম পুনর্বিবেচনায় ফিরে এসেছি তবে এটি রয়েছে "old_location/*.*। আমি সমন্বিত একটি সংশোধনী পাই না "old_location/."
আসফ

@ আসফ: আপনার রোলব্যাকটি ঠিক আছে, ইতিহাস দেখুন ... আমার অর্থ ছিলcopy ("old_location/.","new_location/");
ফেলিক্স ক্লিং

3
@ ডেভ আপনি কখন গ্রহণ করবেন :)?
নাম জি ভিইউ

উত্তর:


239

দেখে মনে হচ্ছে অনুলিপি কেবলমাত্র একক ফাইলগুলি হ্যান্ডেল করে । এখানে আমি খুঁজে পাওয়া যাও recursively অনুলিপি করার জন্য একটি ফাংশন এই নোটটি উপর কপি ডকুমেন্টেশন পৃষ্ঠাটিতে :

<?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); 
} 
?>

2
এটি একটি নক্ষত্র এবং তারকা নয়;)
গর্ডন

6
মোহন মত কাজ করে .. ধন্যবাদ @ ফেলিক্সক্লিং
মিলাপ

2
এর @mkdirবদলে কেন mkdir?
অলিবোয় 50

3
@ অলিবয় 50: আপনি 5 বছর আগে কোড লিখেছেন এমন ব্যক্তিকে জিজ্ঞাসা করতে পারেন: php.net/manual/en/function.copy.php#91010 । ত্রুটি বার্তাগুলি দমন করার জন্য সম্ভবত এটি আরও জনপ্রিয় ছিল।
ফেলিক্স ক্লিং

1
@ অলিবয় 50: আমি দেখছি। আমি মনে করি এটি কোনও ত্রুটি বার্তাকে দমন করে। যদিও আমি সত্যিই এটি ব্যবহার করি নি। এটি ডকুমেন্টেশন: us3.php.net/manual/en/language.operators.errorcontrol.php
ফেলিক্স ক্লিং

90

এখানে বর্ণিত হিসাবে এটি এটি অন্য পদ্ধতি যা সিমলিংকেরও যত্ন নেয়:

/**
 * Copy a file, or recursively copy a folder and its contents
 * @author      Aidan Lister <aidan@php.net>
 * @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));
}

140 সাব ফোল্ডার এবং 21 টি ছবি সম্বলিত প্রতিটি সাবফোল্ডার সহ একটি ফোল্ডার অনুলিপি করতে দুর্দান্ত কাজ করেছেন। দুর্দান্ত কাজ! ধন্যবাদ!
Darksaint2014

1
mkdirtrueপুনরাবৃত্তভাবে ডিরেক্টরি সমর্থন করার জন্য সর্বশেষ পরামিতি হিসাবে যুক্ত করা উচিত তবে এই স্ক্রিপ্টটি নিখুঁত
জেনিথস

এটি পুরো ফোল্ডারটি অনুলিপি করে? যদি আপনি কেবল ফোল্ডারের ভিতরে থাকা ফাইলগুলি প্যারেন্ট ফোল্ডার ব্যতীত অনুলিপি করতে চান তবে প্রশ্ন যেমন: এটি copy ("old_location/*.*","new_location/");কি কাজ করে? আপনার যদি ডট ফাইল থাকে তবে সেগুলি কি মিলবে?
এক্সসিএস

35

অনুলিপি () কেবলমাত্র ফাইলের সাথে কাজ করে।

ডস কপি এবং ইউনিক্স সিপি উভয় কমান্ডই পুনরাবৃত্তভাবে অনুলিপি করবে - সুতরাং দ্রুত সমাধান কেবল শেল আউট এবং এগুলি ব্যবহার করা। যেমন

`cp -r $src $dest`;

অন্যথায় আপনাকে opendir/ readdirঅথবা scandirডিরেক্টরিগুলির বিষয়বস্তু পড়তে হবে, ফলাফলগুলির মাধ্যমে পুনরাবৃত্তি করতে হবে এবং যদি__ডির প্রতিটি ক্ষেত্রে সত্য হয়, তবে এটির পুনরাবৃত্তি করুন।

যেমন

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);
        }
    }
}

1
এখানে function xcopy($src, $dest) { foreach (scandir($src) as $file) { $srcfile = rtrim($src, '/') .'/'. $file; $destfile = rtrim($dest, '/') .'/'. $file; if (!is_readable($srcfile)) { continue; } if ($file != '.' && $file != '..') { if (is_dir($srcfile)) { if (!file_exists($destfile)) { mkdir($destfile); } xcopy($srcfile, $destfile); } else { copy($srcfile, $destfile); } } } }
এক্সকপি

ব্যাকটিক সমাধানের জন্য ধন্যবাদ ! এমন একটি পৃষ্ঠা যা আমাকে অনুলিপি করতে সাহায্য করেছিল অনুলিপি কমান্ড: ইউনিক্স সিপি দ্বারা ব্যাখ্যা করা । অতিরিক্ত তথ্য: পিএইচপি> = 5.3 অফার কিছু চমৎকার iterators
maxpower9000

21

সবচেয়ে ভাল সমাধান!

<?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
?>

31
উইন্ডোজ সার্ভার ও অন্যান্য পরিবেশের কাজ যেখানে আপনি হয় উভয় কোন অ্যাক্সেস থাকবে না shell_execবা cp। এটি এটিকে তৈরি করে - আমার মতে - খুব সম্ভবত "সেরা" সমাধান।
পেলমিস্টার

3
এর বাইরে, যখন কেউ আপনার সার্ভারে কোনও ফাইল পাওয়ার কোনও উপায় খুঁজে পায় তখন কোনও পিএইচপি ফাইল থেকে কমান্ডলাইন নিয়ন্ত্রণগুলি একটি বড় সমস্যা হতে পারে।
মার্টিজন

মোহন মত কাজ! CentOS এ এবং এটি দুর্দান্ত কাজ করেছে। ধন্যবাদ @bstpierre
নিক গ্রিন

1
এটি উইন্ডোতে মোটেও কাজ করবে না, কারণ cpএটি একটি লিনাক্স কমান্ড। উইন্ডোজ ব্যবহারের জন্য xcopy dir1 dir2 /e /i, যেখানে /eখালি ডায়ার অনুলিপি করা এবং /iফাইল বা ডিরেক্টরি সম্পর্কে প্রশ্ন উপেক্ষা করার জন্য
মিশেল

হ্যাঁ, যদি আপনার সার্ভারটি এই আদেশটি সমর্থন করে এবং আপনার কাছে অনুমতি প্রয়োজন হয় তবে এটি সর্বোত্তম সমাধান। এটা খুব দ্রুত। দুর্ভাগ্যক্রমে সমস্ত পরিবেশ কাজ করছে না।
mdikici

13
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 );
    }
}

নিখুঁতভাবে কাজ করে! ধন্যবাদ ভাই
রবিন ডেলাপুর্ত

8

অন্য কোথাও যেমন বলা হয়েছে, copyকেবল উত্সের জন্য একটি একক ফাইলের সাথে কাজ করে কোনও প্যাটার্ন নয়। আপনি যদি প্যাটার্ন অনুসারে অনুলিপি করতে চান globতবে ফাইলগুলি নির্ধারণ করতে ব্যবহার করুন, তারপরে অনুলিপিটি চালান। এটি যদিও উপ-ডিরেক্টরিগুলি অনুলিপি করবে না বা এটি গন্তব্য ডিরেক্টরিটি তৈরি করবে না।

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

পরিবর্তনের বিষয়ে বিবেচনা করুন: $ গন্তব্য = রিয়েলপথ (ir দির। DIRECTORY_SEPARATOR)। basename ($ ফাইল); সহ: $ গন্তব্য = রিয়েলপথ (ir দির)। DIRECTORY_SEPARATOR basename ($ ফাইল);
দাওজ

8
<?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 );
        }
    }
?>

শেষ 4 র্থ লাইন থেকে, এটি তৈরি করুন

$source = 'wordpress';//i.e. your source path

এবং

$destination ='b';

7

পুরো ধন্যবাদ অবশ্যই ফেলিক্স ক্লিংকে যেতে হবে তার দুর্দান্ত উত্তরের জন্য যা আমি কৃতজ্ঞতার সাথে আমার কোডটিতে ব্যবহার করেছি। সাফল্য বা ব্যর্থতার প্রতিবেদন করতে আমি বুলিয়ান রিটার্ন মানটির একটি ছোট বর্ধন প্রস্তাব করি:

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;
}

1
আপনি recurse_copy () এবং recurseCopy () ফাংশন নাম হিসাবে ব্যবহার করছেন, এটি আপডেট করুন।
এজলাস উপস্থিতি

ক্লোডির ($ দির); বিবৃতিটি (if reslut === সত্য) বিবৃতিটির বাইরে হওয়া দরকার, অর্থাত একটি কোঁকড়ানো ধনুর্বন্ধনী আরও নিচে। অন্যথায় আপনি মুক্ত না হওয়া সংস্থান থাকা ঝুঁকিপূর্ণ।
দিমিতর দারাজনসকি


5

আমার @ Kzoty উত্তরের ছাঁটাই করা সংস্করণ। ধন্যবাদ জোটি

ব্যবহার

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();
    }

}

1

আমি এসপিএল ডিরেক্টরি 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");

0
// using exec

function rCopy($directory, $destination)
{

    $command = sprintf('cp -r %s/* %s', $directory, $destination);

    exec($command);

}

0

লিনাক্স সার্ভারের জন্য অনুমতি সংরক্ষণের সময় পুনরাবৃত্তভাবে অনুলিপি করার জন্য আপনার কেবল একটি লাইন কোডের প্রয়োজন:

exec('cp -a '.$source.' '.$dest);

এটি করার আরেকটি উপায় হ'ল:

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());
}

তবে এটি ধীরে ধীরে এবং অনুমতিগুলি সংরক্ষণ করে না।


0

আমার একইরকম পরিস্থিতি হয়েছিল যেখানে একই সার্ভারে আমার একটি ডোমেন থেকে অন্য ডোমেইনে অনুলিপি করা দরকার ছিল, আমার ক্ষেত্রে ঠিক কী কাজ হয়েছে তা এখানে আপনার নিজের অনুসারে সামঞ্জস্য করতে পারেন:

foreach(glob('../folder/*.php') as $file) {
$adjust = substr($file,3);
copy($file, '/home/user/abcde.com/'.$adjust);

"সাবস্ট্রটার ()" এর ব্যবহারটি লক্ষ্য করুন, এগুলি ছাড়াই গন্তব্যটি '/home/user/abcde.com/../folder/' হয়ে যায়, এটি এমন কিছু হতে পারে যা আপনি চান না। সুতরাং, আমি কাঙ্ক্ষিত গন্তব্যটি '/home/user/abcde.com/folder/' পেতে প্রথম 3 টি অক্ষর (../) মুছে ফেলার জন্য সাবস্ট্রটার () ব্যবহার করেছি। সুতরাং, আপনার সাবস্ট্রাস্ট () ফাংশন এবং গ্লোব () ফাংশনটি এটি আপনার ব্যক্তিগত প্রয়োজনের সাথে ফিট না করা পর্যন্ত সামঞ্জস্য করতে পারেন। আশাকরি এটা সাহায্য করবে.

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.