25

私の古い 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 では、メイン ディレクトリのみが作成され、ファイルはコピーされません。2 つの VPS の間で何が変わったのかわかりませんか?

4

14 に答える 14

82

次のようなことを試してください:

$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

于 2011-10-15T05:22:14.880 に答える
15

(* nix VPSであると仮定して)システムコールをcp -r実行して、コピーを実行させることをお勧めします。

于 2011-04-18T19:27:29.807 に答える
9

ジョセフのコード (以下) を変更しました。うまくいかなかったからです。これが機能します:

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

[編集] ディレクトリを作成する前にテストを追加 (7 行目)

于 2012-08-14T07:49:02.150 に答える
6

当社で使用しているものは以下のとおりです。

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);
    }
}
于 2012-01-13T13:36:21.187 に答える
2

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());
  }
}
于 2013-11-20T09:38:50.837 に答える
2
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;
}
于 2013-10-14T08:38:43.520 に答える
0

うーん。それは複雑なので))

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

于 2015-05-05T04:08:58.547 に答える
0

ユーザー(グループ)の権限を確認する必要があると思います。たとえば、 (su?)PHP の実行方法に応じて、chmodを検討する必要があります。PHP の設定を変更することもできます。

于 2011-04-18T19:29:10.750 に答える
0
<?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'); ?>
于 2018-02-22T19:19:28.343 に答える
0

スレッドでテストした関数にはいくつかの問題がありましたが、ここにすべてをカバーする強力な関数があります。ハイライト:

  1. 初期または中間のソース ディレクトリを持つ必要はありません。ソースディレクトリとコピーされたディレクトリまでのすべてのディレクトリが処理されます。

  2. 配列からディレクトリまたはファイルをスキップする機能。(オプション)global $skip;ファイルのスキップにより、サブレベルのディレクトリの下でも処理されます。

  3. 完全な再帰サポート、複数の深さのすべてのファイルとディレクトリがサポートされています。

$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);
}
于 2017-11-27T19:12:46.933 に答える
-1

OSにこれを処理するように依頼してみませんか?

system("cp -r olddir newdir");

終わり。

于 2015-12-01T17:28:27.023 に答える