Вчера передо мной встала такая задача - как залить папку с одного сервера на фтп, которое находится на другом сервере? Вроде бы тривиальная задача, но пришлось повозиться, чтобы её решить. Изначально думал найти решение в готовых классах на phpclasses.org, но не тут-то было.. Классов, которые работают с FTP там около десятка, все я смотреть не стал, скачал только штуки 3. Попытался разобраться - получилось переливать только файлы, но не папки.
Я целый час провозился с этими классами и не достиг решения поставленной задачи, после чего решил поискать нужное в гугле, но полчаса поисков толкового решения так и не дали. Была идея достать эту функцию из какого-то готового продукта, но посмотрев на размеры кода, в котором нужно было бы рыться, я понял, что овчинка не стоит выделки.
Тогда я уже плюнул на всё это и за полчаса с помощью мануала по функциям работы с ftp написал простенькую функцию, которая делает то, что мне нужно. Выкладываю здесь, может кому-то пригодиться, т. к. задача распространенная, а готовое решение с ходу найти у меня так и не получилось.
Исходные данные такие: на сервере mainserver.com есть папка mainserver.com/upload/, требуется залить эту папку на ftp.freehost.com в корневую папку для www (public_html обычно).
Для решения задачи на главном сервере на уровень выше, чем папка upload создаётся скрипт uploader.php такого содержания:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <?php $ftp_server = 'ftp.freehost.com'; $ftp_login = 'login'; $ftp_password = 'password'; $local_dir = 'upload'; $ftp_root = '/public_html/'; function do_upload($dir = 'upload') { global $conn_id, $ftp_root, $transfer_mode, $local_dir; $ftp_dir = preg_replace('/^'.$local_dir.'\/?/', '', $dir); if ($ftp_dir != '') echo 'Папка '. $ftp_dir . ((ftp_mkdir($conn_id, $ftp_root . $ftp_dir)) ? ' создана' : ' не создана').'<br />'; $filelist = glob(($dir!='') ? $dir.'/*' : '*'); if ($filelist == array()) return 0; foreach ($filelist as $file) { if (is_file($file)) { $transfer_mode = (preg_match('/\.(gif|jpg|png)$/', $file)) ? FTP_BINARY : FTP_ASCII; echo 'Файл ' . $file . ((ftp_put($conn_id, $ftp_root . preg_replace('/^'.$local_dir.'\//', '', $file), $file, $transfer_mode)) ? ' загружен' : ' не загружен').'<br />'; } else do_upload($file); } return 0; } $conn_id = ftp_connect($ftp_server); $login_result = ftp_login($conn_id, $ftp_login, $ftp_password); if (!$conn_id || !$login_result) exit("Не удалось установить соединение с FTP сервером!\nПопытка подключения к серверу $ftp_server!"); else echo "Установлено соединение с FTP сервером $ftp_server<br />"; do_upload($local_dir); ftp_close($conn_id); ?> |
Естественно, в первых строках нужно поменять $ftp_server, $ftp_login, $ftp_password на свои адрес фтп, логин и пароль.
$local_dir - папка на главном сервере, которую надо залить на сторонний ftp.
$ftp_root - корневая папка на фрихосте.
При работе скрипт с помощью рекурсивной функции проходит все вложенные в upload папки и заливает их содержимое на указанный фтп-сервер. В браузер выводится log работы скрипта такого вида:
Установлено соединение с FTP сервером ftp.freehost.com
Файл upload/file.htm загружен
Файл upload/frm.php загружен
Файл upload/index.htm загружен
Папка other создана
Файл upload/other/load.php загружен
Скрипт самостоятельно по расширению закачиваемого файла выбирает режим закачки FTP_BINARY или FTP_ASCII. Сейчас в бинарном режиме передаются только картинки, если понадобится заливать в нём еще что-то, то нужно изменить фрагмент кода gif|jpg|png на тот, который необходим, например, на avi|rar|wav|gif|jpg|png.
Март 8th, 2008 at 15:39
А у меня скрипт не захотел переносить файлы, только дерево папок перенёс….
Март 11th, 2008 at 16:25
А какие ошибки выдаёт?
Март 13th, 2008 at 0:03
кмоды хыхы
Апрель 8th, 2008 at 11:57
Ай, спасибо, молодец! Только вчера встала передо мной точь-в-точь задача. Я даже PEAR поставил… но он, собака, не хочет рекурсивно закачивать на FTP(обратно скачивает правильно) Обратная ссылка с меня.
Апрель 8th, 2008 at 13:16
[...] решение в гугле(им я и воспользовался) предложил Зверобой. Его я привожу полностью: $ftp_server = ‘ftp.freehost.com’; $ftp_login = [...]
Апрель 8th, 2008 at 17:54
Да не за что… Я тоже сначала на PEAR посмотрел, но не нашёл там нужной функции, поэтому и написал эту. О недочетах вроде этого “если папка на сервере уже есть, то он всё равно пытается её создать” на момент создания не задумывался. А в действующем проекте это стало даже плюсом, т.к. мне нужно было с главного сервера время от времени заливать файлы на фрихосты, перезаписывая существующие.
Июль 26th, 2008 at 19:19
Благодарю за столь полезную функцию. Как раз потребовалось сделать подобное..
Сентябрь 29th, 2008 at 13:32
Спасибо! Очень помогло.
Ноябрь 19th, 2009 at 13:24
Если у Вас возникает ошибка: I won’t open a connection to… нужно перевести соединение в пассивный режим. Добавьте строчку: ftp_pasv($conn_id, true);
Перед: do_upload($local_dir);
И всё заработает.
Январь 25th, 2010 at 15:25
global $conn_id, $ftp_root, $transfer_mode, $local_dir;
- это очень плохо. У функций есть АРГУМЕНТЫ для этих целей.
Январь 25th, 2010 at 20:36
Хотите передавать 5 лишних переменных при каждом вызове функции - пожалуйста…
Февраль 5th, 2010 at 10:53
Кто может посоветовать скрипт, который через PHP загружает все файлы из папки на компе в папку на сервер?
При этом, необходимо чтобы после загрузки, имена файлов были доступны в качестве переменных (для занесения в базу и т.д.)
Заранее благодарен
Февраль 5th, 2010 at 12:55
Mike, эта задача средствами только php, html, и javascript вряд ли осуществима.
Практически везде, когда речь идёт о загрузке файлов с клиентского компьютера на сервер, мы видим поля для каждого файла отдельно. А полностью все файлы папки загрузить нельзя, т.к. у браузера нет доступа к информации о файлах в конкретной папке (из соображений безопасности это сделано).
Но видел реализацию такого во флэше - на вконтакте недавно сделали такую фишку как загрузка всех файлов из папки. И еще разработчики писали - смотрите, мол, как мы круто придумали. И правда круто, такого решения я ещё не видел. В общем, советую глянуть в сторону флэша.
Февраль 6th, 2010 at 22:30
млин… а мне как раз надо залить папку целиком… сижу думаю как быть…. флеш ковырять- слишком долго и трудозатратно
Февраль 19th, 2010 at 11:12
Для закачке нескольких файлов, есть плагины от JQuery (используются технологии: JQuery, ajax, PHP, MySQL)