Заливка папки на FTP

Скрипты Прокомментировать

Вчера передо мной встала такая задача – как залить папку с одного сервера на фтп, которое находится на другом сервере? Вроде бы тривиальная задача, но пришлось повозиться, чтобы её решить. Изначально думал найти решение в готовых классах на 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.

Комментарии (24) к “Заливка папки на FTP”

  1. smash:

    А у меня скрипт не захотел переносить файлы, только дерево папок перенёс….

  2. zweroboy:

    А какие ошибки выдаёт?

  3. блбл:

    кмоды хыхы

  4. CrewDoo:

    Ай, спасибо, молодец! Только вчера встала передо мной точь-в-точь задача. Я даже PEAR поставил… но он, собака, не хочет рекурсивно закачивать на FTP(обратно скачивает правильно) Обратная ссылка с меня.

  5. Загрузка папок по FTP рекурсивно | Блог летчика-парашютиста:

    [...] решение в гугле(им я и воспользовался) предложил Зверобой. Его я привожу полностью: $ftp_server = ‘ftp.freehost.com’; $ftp_login = [...]

  6. zweroboy:

    Да не за что… Я тоже сначала на PEAR посмотрел, но не нашёл там нужной функции, поэтому и написал эту. О недочетах вроде этого «если папка на сервере уже есть, то он всё равно пытается её создать» на момент создания не задумывался. А в действующем проекте это стало даже плюсом, т.к. мне нужно было с главного сервера время от времени заливать файлы на фрихосты, перезаписывая существующие.

  7. Oleg:

    Благодарю за столь полезную функцию. Как раз потребовалось сделать подобное..

  8. scorro:

    Спасибо! Очень помогло.

  9. TheSnob:

    Если у Вас возникает ошибка: I won’t open a connection to… нужно перевести соединение в пассивный режим. Добавьте строчку: ftp_pasv($conn_id, true);
    Перед: do_upload($local_dir);
    И всё заработает.

  10. Zeev:

    global $conn_id, $ftp_root, $transfer_mode, $local_dir;

    - это очень плохо. У функций есть АРГУМЕНТЫ для этих целей.

  11. zweroboy:

    Хотите передавать 5 лишних переменных при каждом вызове функции – пожалуйста…

  12. Mike:

    Кто может посоветовать скрипт, который через PHP загружает все файлы из папки на компе в папку на сервер?
    При этом, необходимо чтобы после загрузки, имена файлов были доступны в качестве переменных (для занесения в базу и т.д.)

    Заранее благодарен

  13. zweroboy:

    Mike, эта задача средствами только php, html, и javascript вряд ли осуществима.
    Практически везде, когда речь идёт о загрузке файлов с клиентского компьютера на сервер, мы видим поля для каждого файла отдельно. А полностью все файлы папки загрузить нельзя, т.к. у браузера нет доступа к информации о файлах в конкретной папке (из соображений безопасности это сделано).
    Но видел реализацию такого во флэше – на вконтакте недавно сделали такую фишку как загрузка всех файлов из папки. И еще разработчики писали – смотрите, мол, как мы круто придумали. И правда круто, такого решения я ещё не видел. В общем, советую глянуть в сторону флэша.

  14. yadino:

    млин… а мне как раз надо залить папку целиком… сижу думаю как быть…. флеш ковырять- слишком долго и трудозатратно

  15. sys2:

    Для закачке нескольких файлов, есть плагины от JQuery (используются технологии: JQuery, ajax, PHP, MySQL)

  16. бро:

    Спасибо бро, выручил, то что нужно!

  17. Devils:

    Ребят, а как скачать с ftp-сервера папку (Допустим http://ftp.name.ru/test1/test2) со всем ее содержимым, т.е. папки с файлы в локальную папку ./test2?
    Если можно, приведите пример php-кода.

  18. zweroboy:

    Оно конечно можно, только какой смысл в этом мероприятии?
    С этой задачей справляется любой фтп-клиент!

  19. Devils:

    zwerobе oy, Да я знаю ;) Если бы этого не надо было, то и не писал… Просто в php я еще не особо силен… Поэтому и прошу чужой помощи.

  20. zweroboy:

    Devils, будет свободный часик – напишу…

  21. Lego:

    Спасибо огромное! Как раз то что нужно!

  22. Lego:

    Спасибо огромное! Как раз то, что нужно!

  23. Egor:

    пригодилось, спасибо.

  24. Антон:

    Здравствуйте!А как с сайта скачать целую папку вместе со всем, что находится в этой папке?

Прокомментировать

Сообщения в RSS Комментарии в RSS Войти