Recursive Copy of Directory

前端 未结 14 940
花落未央
花落未央 2020-12-08 15:14

On my old VPS I was using the following code to copy the files and directories within a directory to a new directory that was created after the user submitted their form.

相关标签:
14条回答
  • 2020-12-08 15:24

    Try something like this:

    $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 iterate through all folders and subfolders and make copy of files from $source to $dest

    0 讨论(0)
  • 2020-12-08 15:28

    Could I suggest that (assuming it's a *nix VPS) that you just do a system call to cp -r and let that do the copy for you.

    0 讨论(0)
  • 2020-12-08 15:28

    I have changed Joseph's code (below), because it wasn't working for me. This is what works:

    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] added test before creating a directory (line 7)

    0 讨论(0)
  • 2020-12-08 15:29

    I guess you should check user(group)rights. You should consider chmod for example, depending on how you run (su?)PHP. You could possibly also choose to modify your php configuration.

    0 讨论(0)
  • 2020-12-08 15:29
    <?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'); ?>
    
    0 讨论(0)
  • 2020-12-08 15:34

    The Symfony's FileSystem Component offers a good error handling as well as recursive remove and other useful stuffs. Using @OzzyCzech's great answer, we can do a robust recursive copy this way:

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

    Note: you can use this component as well as all other Symfony2 components standalone.

    0 讨论(0)
提交回复
热议问题