На моем старом 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
Я изменил код Джозефа (ниже), потому что он не работал для меня. Это то, что работает:
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); } }
в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)
Могу ли я предположить, что (при условии, что это Vix Vix), вы просто выполняете системный вызов cp -r
и позволяете ему делать копию для вас.
Вот что мы используем в нашей компании:
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); } }
в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); } }
Компонент FileSystem 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()); } }
Примечание. Вы можете использовать этот компонент, а также все остальные компоненты Symfony2 автономно.
Эта функция копирует папку 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; }
Я думаю, вы должны проверить права пользователя (группы). Вы должны рассмотреть chmod, например, в зависимости от того, как вы запускаете (su?) PHP. Возможно, вы также захотите изменить свою конфигурацию 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
– somthing, подобный этому www/folder/ahah/file.txt
Вот простая рекурсивная функция для копирования целых каталогов
источник: 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); } ?>
Почему бы просто не попросить ОС позаботиться об этом?
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); }