@ Феликс: Мне было интересно то же самое. Я откатился на первую ревизию но она есть "old_location/*.*. Я не могу найти ревизию, содержащую "old_location/.".
Асаф
@Asaph: Ваш откат был в порядке, посмотрите на историю ... Я имел в видуcopy ("old_location/.","new_location/");
@ Oliboy50: Вы можете спросить человека, который написал код 5 лет назад: php.net/manual/en/function.copy.php#91010 . Возможно, тогда было популярнее подавлять сообщения об ошибках.
Отлично работало, чтобы скопировать папку с 140 подпапками и каждой подпапкой, содержащей 21 изображение. Прекрасно работает! Спасибо!
Darksaint2014
1
mkdirдолжен быть добавлен trueв качестве последнего параметра для поддержки рекурсивной директории, тогда этот скрипт идеален
ZenithS
Это копирует всю папку? Что если вы хотите скопировать файлы только внутри папки, без родительской папки, как указано в вопросе: copy ("old_location/*.*","new_location/");это работает? Что если у вас есть точечные файлы, будут ли они сопоставлены?
XCS
35
copy () работает только с файлами.
Обе команды DOS copy и Unix cp будут копировать рекурсивно, поэтому самое быстрое решение - просто раскошелиться и использовать их. например
`cp -r $src $dest`;
В противном случае вам нужно будет использовать opendir/ readdirили, scandirчтобы прочитать содержимое каталога, перебрать результаты, и если is_dir вернет true для каждого из них, вернитесь в него.
Вот более стабильная и более чистая версия xcopy (), которая не создает папку, если она существует: function xcopy($src, $dest) { foreach (scandir($src) as $file) { $srcfile = rtrim($src, '/') .'/'. $file; $destfile = rtrim($dest, '/') .'/'. $file; if (!is_readable($srcfile)) { continue; } if ($file != '.' && $file != '..') { if (is_dir($srcfile)) { if (!file_exists($destfile)) { mkdir($destfile); } xcopy($srcfile, $destfile); } else { copy($srcfile, $destfile); } } } }
TheStoryCoder
Спасибо за обратное решение ! Страница, которая помогла мне настроить команду копирования: UNIX cp объяснил . Дополнительная информация: PHP> = 5.3 предлагает несколько хороших итераторов
Не будет работать на серверах Windows , или других средах , где вы либо не имеют доступа к любому shell_execили cp. Это делает это - по моему мнению - едва ли "лучшим" решением.
Pellmeister
3
Кроме того, управление командной строкой из файла PHP может быть большой проблемой, когда кто-то находит способ получить файл на вашем сервере.
Мартейн
Работал как шарм! На CentOS и он работал отлично. Спасибо @bstpierre
Ник Грин
1
Это не будет работать на Windows вообще, потому что cpэто команда Linux. Для использования в Windows xcopy dir1 dir2 /e /i, где /eозначает копирование пустых папок и /iигнорирование вопросов о файлах или каталогах
Мишель
Да, это лучшее решение, если ваш сервер поддерживает эту команду и у вас есть необходимые разрешения. Это очень быстро. К сожалению, не работает во всех средах.
Как сказано в другом месте, copyработает только с одним файлом для источника, а не шаблон. Если вы хотите копировать по шаблону, используйте globдля определения файлов, затем запустите копирование. Это не скопирует подкаталоги, хотя и не создаст каталог назначения.
function copyToDir($pattern, $dir){foreach(glob($pattern)as $file){if(!is_dir($file)&& is_readable($file)){
$dest = realpath($dir . DIRECTORY_SEPARATOR). basename($file);
copy($file, $dest);}}}
copyToDir('./test/foo/*.txt','./test/bar');// copies all txt files
рассмотрите возможность изменения: $ dest = realpath ($ dir. DIRECTORY_SEPARATOR). Базовое имя ($ файла); с: $ dest = realpath ($ dir). DIRECTORY_SEPARATOR. Базовое имя ($ файла);
Я должен поблагодарить Феликса Клинга за отличный ответ, который я с благодарностью использовал в своем коде. Я предлагаю небольшое улучшение логического возвращаемого значения, чтобы сообщить об успехе или неудаче:
Вы используете recurse_copy () и recurseCopy () в качестве имен функций, обновите их.
AgelessEssence
Закрытый ($ dir); оператор должен находиться за пределами оператора if ($ reslut === true), то есть на одну фигурную скобку ниже. В противном случае вы рискуете получить не освобожденные ресурсы.
Моя обрезанная версия ответа @Kzoty. Спасибо, Кзоты.
использование
Helper::copy($sourcePath, $targetPath);classHelper{staticfunction copy($source, $target){if(!is_dir($source)){//it is a file, do a normal copy
copy($source, $target);return;}//it is a folder, copy its files & sub-folders@mkdir($target);
$d = dir($source);
$navFolders = array('.','..');while(false!==($fileEntry=$d->read())){//copy one by one//skip if it is navigation folder . or ..if(in_array($fileEntry, $navFolders)){continue;}//do copy
$s ="$source/$fileEntry";
$t ="$target/$fileEntry";self::copy($s, $t);}
$d->close();}}
У меня была похожая ситуация, когда мне нужно было копировать из одного домена в другой на том же сервере. Вот именно то, что сработало в моем случае, вы также можете настроить в соответствии с вашим:
Обратите внимание на использование «substr ()», без которого местом назначения становится «/home/user/abcde.com/../folder/», что может быть тем, что вам не нужно. Итак, я использовал substr (), чтобы убрать первые 3 символа (../), чтобы получить желаемый пункт назначения, который называется /home/user/abcde.com/folder/. Таким образом, вы можете настроить функцию substr (), а также функцию glob (), пока она не будет соответствовать вашим личным потребностям. Надеюсь это поможет.
"old_location/."
была просто опечатка?"old_location/*.*
. Я не могу найти ревизию, содержащую"old_location/."
.copy ("old_location/.","new_location/");
Ответы:
Кажется, что копия обрабатывает только отдельные файлы . Вот функция для рекурсивного копирования, которую я нашел в этой заметке на странице документации по копированию :
источник
@mkdir
вместоmkdir
?Как описано здесь , это еще один подход, который также заботится о символических ссылках:
источник
mkdir
должен быть добавленtrue
в качестве последнего параметра для поддержки рекурсивной директории, тогда этот скрипт идеаленcopy ("old_location/*.*","new_location/");
это работает? Что если у вас есть точечные файлы, будут ли они сопоставлены?copy () работает только с файлами.
Обе команды DOS copy и Unix cp будут копировать рекурсивно, поэтому самое быстрое решение - просто раскошелиться и использовать их. например
В противном случае вам нужно будет использовать
opendir
/readdir
или,scandir
чтобы прочитать содержимое каталога, перебрать результаты, и если is_dir вернет true для каждого из них, вернитесь в него.например
источник
function xcopy($src, $dest) { foreach (scandir($src) as $file) { $srcfile = rtrim($src, '/') .'/'. $file; $destfile = rtrim($dest, '/') .'/'. $file; if (!is_readable($srcfile)) { continue; } if ($file != '.' && $file != '..') { if (is_dir($srcfile)) { if (!file_exists($destfile)) { mkdir($destfile); } xcopy($srcfile, $destfile); } else { copy($srcfile, $destfile); } } } }
Лучшее решение!
источник
shell_exec
илиcp
. Это делает это - по моему мнению - едва ли "лучшим" решением.cp
это команда Linux. Для использования в Windowsxcopy dir1 dir2 /e /i
, где/e
означает копирование пустых папок и/i
игнорирование вопросов о файлах или каталогахисточник
Как сказано в другом месте,
copy
работает только с одним файлом для источника, а не шаблон. Если вы хотите копировать по шаблону, используйтеglob
для определения файлов, затем запустите копирование. Это не скопирует подкаталоги, хотя и не создаст каталог назначения.источник
из последней 4-й строки, сделайте это
и
источник
Я должен поблагодарить Феликса Клинга за отличный ответ, который я с благодарностью использовал в своем коде. Я предлагаю небольшое улучшение логического возвращаемого значения, чтобы сообщить об успехе или неудаче:
источник
С Symfony это очень легко сделать:
См. Https://symfony.com/doc/current/components/filesystem.html.
источник
Моя обрезанная версия ответа @Kzoty. Спасибо, Кзоты.
использование
источник
Я клонирую весь каталог с помощью SPL Directory Iterator.
источник
источник
Для серверов Linux вам просто нужна одна строка кода для рекурсивного копирования с сохранением разрешения:
Еще один способ сделать это:
но это медленнее и не сохраняет разрешения.
источник
У меня была похожая ситуация, когда мне нужно было копировать из одного домена в другой на том же сервере. Вот именно то, что сработало в моем случае, вы также можете настроить в соответствии с вашим:
Обратите внимание на использование «substr ()», без которого местом назначения становится «/home/user/abcde.com/../folder/», что может быть тем, что вам не нужно. Итак, я использовал substr (), чтобы убрать первые 3 символа (../), чтобы получить желаемый пункт назначения, который называется /home/user/abcde.com/folder/. Таким образом, вы можете настроить функцию substr (), а также функцию glob (), пока она не будет соответствовать вашим личным потребностям. Надеюсь это поможет.
источник