a

Câu hỏi Sao chép đệ quy của thư mục


Trên VPS cũ của tôi, tôi đã sử dụng đoạn mã sau để sao chép các tập tin và thư mục trong một thư mục vào một thư mục mới được tạo sau khi người dùng gửi biểu mẫu của họ.

function copyr($source, $dest)
{
   // Simple copy for a file
   if (is_file($source)) {
      return copy($source, $dest);
   }

   // Make destination directory
   if (!is_dir($dest)) {
      mkdir($dest);
      $company = ($_POST['company']);
   }

   // Loop through the folder
   $dir = dir($source);
   while (false !== $entry = $dir->read()) {
      // Skip pointers
      if ($entry == '.' || $entry == '..') {
         continue;
      }

      // Deep copy directories
      if ($dest !== "$source/$entry") {
         copyr("$source/$entry", "$dest/$entry");
      }
   }

   // Clean up
   $dir->close();
   return true;
}

copyr('Template/MemberPages', "Members/$company")

Tuy nhiên bây giờ trên VPS mới của tôi nó sẽ chỉ tạo ra các thư mục chính, nhưng sẽ không sao chép bất kỳ của các tập tin vào nó. Tôi không hiểu những gì có thể đã thay đổi giữa 2 VPS?


17
2018-04-18 19:25


gốc


Mã của bạn sẽ dễ đọc hơn nếu bạn thụt vào mỗi khối. - Doug T.
Có thể là phiên bản PHP, hãy thử đệ quy sao chép chức năng từ hướng dẫn sử dụng php. - SIFE
SIFE - Đã thử một cái và nó cũng không hoạt động. Vì vậy, không chắc chắn những gì tôi đang làm sai. Nhưng tôi chỉ sao chép mã, nhập đường dẫn nguồn và đích của tôi và đảm bảo rằng chmod đã được đặt xong, nhưng nó vẫn không hoạt động - Jason
@ Jasom có ​​thể là bạn không có đủ quyền trong thư mục đích để sao chép vào nó. - SIFE
wtf bạn đang làm với $ _POST toàn cầu ở đây? điều này giết chết cách tiếp cận chung hoàn toàn và làm cho func không sử dụng được cho tôi - nhưng dù sao cũng có những ví dụ tốt trong các câu trả lời :) - jebbie


Các câu trả lời:


Hãy thử một cái gì đó như thế này:

$source = "dir/dir/dir";
$dest= "dest/dir";

mkdir($dest, 0755);
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());
  }
}

Iterator lặp qua tất cả các thư mục và thư mục con và sao chép các tệp từ $source đến $dest


70
2017-10-15 05:22



Nếu bạn đang sử dụng Zend Guard, hãy chắc chắn khi sử dụng $ iterator-> getSubPathName () để gọi nó là một hàm ẩn danh. Những gì làm việc cho tôi là: call_user_func_array (array ($ iterator, "getSubPathName"), array ()); - Someone13
Cảm ơn OzzyCzech Very Helpfull Script for .. nhưng tôi cũng muốn sao lưu cơ sở dữ liệu của tôi, xin vui lòng nói về quá trình đó hoặc viết kịch bản hoặc cho tôi bất kỳ liên kết cho rằng - Syed Arif Iqbal
Làm việc của nó !!! upvoted - Mansoorkhan Cherupuzha
có thể muốn xem xét tham số thứ 3 của true trên mkdir để đệ quy tạo thư mục đích tức là mkdir ($ dest, 0755, true); cho mỗi (... - Andrew
Làm RecursiveIteratorIterator thực hiện một __call() phương pháp chuyển tiếp getSubPathName() với trường hợp của RecursiveDirectoryIterator hoặc nó hoạt động như thế nào? - David


Tôi có thể đề nghị rằng (giả sử nó là một * nix VPS) mà bạn chỉ cần thực hiện một cuộc gọi hệ thống đến cp -r và để điều đó làm bản sao cho bạn.


10
2018-04-18 19:27





Tôi đã thay đổi mã của Joseph (dưới đây), bởi vì nó không làm việc cho tôi. Đây là những gì làm việc:

function cpy($source, $dest){
    if(is_dir($source)) {
        $dir_handle=opendir($source);
        while($file=readdir($dir_handle)){
            if($file!="." && $file!=".."){
                if(is_dir($source."/".$file)){
                    if(!is_dir($dest."/".$file)){
                        mkdir($dest."/".$file);
                    }
                    cpy($source."/".$file, $dest."/".$file);
                } else {
                    copy($source."/".$file, $dest."/".$file);
                }
            }
        }
        closedir($dir_handle);
    } else {
        copy($source, $dest);
    }
}

[EDIT] đã thêm kiểm tra trước khi tạo thư mục (dòng 7)


8
2017-08-14 07:49



Kịch bản này vẫn không hoạt động (trong trường hợp của tôi). - Armin


Dưới đây là những gì chúng tôi sử dụng tại công ty của chúng tôi:

static public function copyr($source, $dest)
{
    // recursive function to copy
    // all subdirectories and contents:
    if(is_dir($source)) {
        $dir_handle=opendir($source);
        $sourcefolder = basename($source);
        mkdir($dest."/".$sourcefolder);
        while($file=readdir($dir_handle)){
            if($file!="." && $file!=".."){
                if(is_dir($source."/".$file)){
                    self::copyr($source."/".$file, $dest."/".$sourcefolder);
                } else {
                    copy($source."/".$file, $dest."/".$file);
                }
            }
        }
        closedir($dir_handle);
    } else {
        // can also handle simple copy commands
        copy($source, $dest);
    }
}

5
2018-01-13 13:36



Nó cần phải thêm nếu (! File_exists ($ dest. "/". $ Sourcefolder)) kiểm tra trước mkdir ($ dest. "/". $ Sourcefolder); trong trường hợp các thư mục tồn tại - Pavel Nazarov


Các Thành phần FileSystem của Symfony cung cấp xử lý lỗi tốt cũng như loại bỏ đệ quy và các nội dung hữu ích khác. Sử dụng câu trả lời tuyệt vời của @ OzzyCzech, chúng tôi có thể làm một bản sao đệ quy mạnh mẽ theo cách này:

use Symfony\Component\Filesystem\Filesystem;

// ...

$fileSystem = new FileSystem();

if (file_exists($target))
{
    $this->fileSystem->remove($target);
}

$this->fileSystem->mkdir($target);

$directoryIterator = new \RecursiveDirectoryIterator($source, \RecursiveDirectoryIterator::SKIP_DOTS);
$iterator = new \RecursiveIteratorIterator($directoryIterator, \RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $item)
{
    if ($item->isDir())
    {
        $fileSystem->mkdir($target . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
    }
    else
    {
        $fileSystem->copy($item, $target . DIRECTORY_SEPARATOR . $iterator->getSubPathName());
    }
}

Lưu ý: bạn có thể sử dụng thành phần này cũng như tất cả các thành phần Symfony2 khác độc lập.


5
2017-12-04 09:35





Chức năng này sao chép thư mục recursivley rất chắc chắn. Tôi đã sao chép nó từ phần bình luận trên lệnh sao chép của php.net

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
2018-04-25 08:21



Đã làm cho tôi :) - Felix Eve


OzzyCheck của là thanh lịch và bản gốc, nhưng ông đã quên mkdir ban đầu ($ dest); Xem bên dưới. Không lệnh sao chép nào được cung cấp chỉ với nội dung. Nó phải hoàn thành toàn bộ vai trò của nó.

$source = "dir/dir/dir";
$dest= "dest/dir";

mkdir($dest, 0755);
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());
  }
}

2
2017-11-20 09:38



Bạn nên kiểm tra xem các thư mục tồn tại trước khi tạo ra nó. - Works for a Living


function recurse_copy($source, $dest)
{
    // 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);
    }

    // Loop through the folder
    $dir = dir($source);
    while (false !== $entry = $dir->read()) {
        // Skip pointers
        if ($entry == '.' || $entry == '..') {
            continue;
        }

        // Deep copy directories
        recurse_copy("$source/$entry", "$dest/$entry");
    }

    // Clean up
    $dir->close();
    return true;
}

2
2017-10-14 08:38