目录的递归副本

| 在旧的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\")
但是,现在在我的新VPS上,它将仅创建主目录,而不会将任何文件复制到该主目录。我不了解两个VPS之间可能发生了什么变化?
已邀请:
尝试这样的事情:
$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());
  }
}
迭代器遍历所有文件夹和子文件夹,并将文件从
$source
复制到
$dest
我可以建议(假设它是一个* nix VPS),您只是对
cp -r
进行系统调用,然后让它为您完成复制。
我已经更改了约瑟夫的代码(如下),因为它对我不起作用。这是可行的:
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]在创建目录之前添加了测试(第7行)
Symfony \的FileSystem组件提供了良好的错误处理以及递归删除和其他有用的东西。使用@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());
    }
}
注意:您可以独立使用此组件以及所有其他Symfony2组件。
这是我们在公司中使用的:
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);
    }
}
此功能复制文件夹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); 
}
OzzyCheck的风格优雅原始,但他忘记了最初的mkdir($ dest); 见下文。仅内容不提供复制命令。它必须履行其全部职责。
$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());
  }
}
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;
}
这是复制整个目录的简单递归函数 来源:http://php.net/manual/de/function.copy.php
<?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); 
} 
?>
我想您应该检查用户(组)权限。例如,应根据运行(su?)PHP的方式考虑使用chmod。您可能还可以选择修改您的php配置。
嗯。因为那很复杂))
function mkdir_recursive( $dir ){
  $prev = dirname($dir);
  if( ! file_exists($prev))
  {
    mkdir_recursive($prev);
  }
  if( ! file_exists($dir))
  {
     mkdir($dir);
  }
}

...

foreach( $files as $file){
  mkdir_recursive( dirname( $dir_d . $file));
  copy( $dir_s . $file, $dir_d . $file);
}
$file
-像这样的东西
www/folder/ahah/file.txt
为什么不要求操作系统来解决这个问题呢?
system(\"cp -r olddir newdir\");
做完了
我在线程中测试的功能存在一些问题,这是一个涵盖所有内容的强大功能。强调: 无需具有初始或中间源目录。直到源目录和复制目录的所有目录都将被处理。 能够从阵列中跳过目录或文件。 (可选)使用
global $skip;
时,即使在子目录下也可以跳过文件。 全面的递归支持,所有深度的所有文件和目录均受支持。
$from = \"/path/to/source_dir\";
$to = \"/path/to/destination_dir\";
$skip = array(\'some_file.php\', \'somedir\');

copy_r($from, $to, $skip);

function copy_r($from, $to, $skip=false) {
    global $skip;
    $dir = opendir($from);
    if (!file_exists($to)) {mkdir ($to, 0775, true);}
    while (false !== ($file = readdir($dir))) {
        if ($file == \'.\' OR $file == \'..\' OR in_array($file, $skip)) {continue;}

        if (is_dir($from . DIRECTORY_SEPARATOR . $file)) {
            copy_r($from . DIRECTORY_SEPARATOR . $file, $to . DIRECTORY_SEPARATOR . $file);
        }
        else {
            copy($from . DIRECTORY_SEPARATOR . $file, $to . DIRECTORY_SEPARATOR . $file);
        }
    }
    closedir($dir);
}
<?php

/**
 * code by Nk (nk.have.a@gmail.com)
 */

class filesystem
{
    public static function normalizePath($path)
    {
        return $path.(is_dir($path) && !preg_match(\'@/$@\', $path) ? \'/\' : \'\');      
    }

    public static function rscandir($dir, $sort = SCANDIR_SORT_ASCENDING)
    {
        $results = array();

        if(!is_dir($dir))
        return $results;

        $dir = self::normalizePath($dir);

        $objects = scandir($dir, $sort);

        foreach($objects as $object)
        if($object != \'.\' && $object != \'..\')
        {
            if(is_dir($dir.$object))
            $results = array_merge($results, self::rscandir($dir.$object, $sort));
            else
            array_push($results, $dir.$object);
        }

        array_push($results, $dir);

        return $results;
    }

    public static function rcopy($source, $dest, $destmode = null)
    {
        $files = self::rscandir($source);

        if(empty($files))
        return;

        if(!file_exists($dest))
        mkdir($dest, is_int($destmode) ? $destmode : fileperms($source), true);

        $source = self::normalizePath(realpath($source));
        $dest = self::normalizePath(realpath($dest));

        foreach($files as $file)
        {
            $file_dest = str_replace($source, $dest, $file);

            if(is_dir($file))
            {
                if(!file_exists($file_dest))
                mkdir($file_dest, is_int($destmode) ? $destmode : fileperms($file), true);
            }
            else
            copy($file, $file_dest);
        }
    }
}

?>
/var/www/websiteA/backup.php:
<?php /* include.. */ filesystem::rcopy(\'/var/www/websiteA/\', \'../websiteB\'); ?>

要回复问题请先登录注册