目录的递归副本

Jas*_*son 21 php copy dir

在我的旧VPS上,我使用以下代码将目录中的文件和目录复制到用户提交表单后创建的新目录.

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")
Run Code Online (Sandbox Code Playgroud)

但是现在在我的新VPS上它只会创建主目录,但不会将任何文件复制到它.我不明白2 VPS之间会发生什么变化?

Ozz*_*ech 76

尝试这样的事情:

$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());
  }
}
Run Code Online (Sandbox Code Playgroud)

迭代器遍历所有文件夹和子文件夹和文件制作副本从$source$dest

  • 可能需要考虑 mkdir 上的第三个参数 true 以递归方式创建目标目录,即 mkdir($dest, 0755, true); foreach (... (2认同)

Jam*_*s C 13

我可以建议(假设它是*nix VPS)你只是进行系统调用cp -r并让它为你做副本.


Bel*_*voj 8

我已经改变了约瑟夫的代码(下面),因为它不适合我.这是有效的:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

[EDIT]在创建目录之前添加了测试(第7行)


Arm*_*min 6

这个函数复制文件夹recursivley 非常可靠。我已经从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); 
}
Run Code Online (Sandbox Code Playgroud)


Ala*_*blo 6

Symfony的的文件系统组件提供了一个良好的错误处理以及递归删除和其他有用的东西.使用@ OzzyCzech的好答案,我们可以通过这种方式执行强大的递归复制:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:您可以单独使用此组件以及所有其他Symfony2组件.

  • Symfony 文件系统组件有一个 [mirror](https://symfony.com/doc/current/components/filesystem.html#mirror) 方法: `$filesystem->mirror('/​​path/to/source', '/路径/到/目标');` (2认同)

Jos*_*son 5

以下是我们在公司使用的内容:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)