Протокол передачи FTP (File Trasfer Protocol) является одним из старейших прикладных протоколов, появившихся задолго до Web в 1971 году. До начала 90-х годов на долю FTP приходилась половина трафика всей сети Интернет. Этот протокол и по сегодняшний день используется для распространения програмного обеспечения и доступа к удаленным хостам. В данном разделе будет рассмотрена разработка веб-приложения, обеспечивающего доступ по протоколу HTTP к удаленному серверу FTP как с другого удаленного сервера, так и слокальной машины, на которой работает сервер Apache с поддержкой РНР.
Соединение с сервером устанавливается при помощи функции ftp_connect(), имеющей следующий синтаксис:
resource ftp_connect(string host [, int port [, int timeout]])
Функция принимает в качестве первого параметра host адрес FTP-сервера. Через второй необязательный параметр port можно передать значение порта, по которому устанавливается соединение. По умолчанию соединение устанавливается по стандартному 21 порту. При помощи третьего параметра timeout можно указать время в секундах, в течении которого функция будет ожидать ответа от сервера. По умолчанию, если данный параметр не задан, функция ожидает ответ 90 секунд. В случае, если установить соединение не удалось, функция возвращает false. При успешном соединении с FTP-сервером функция возвращает дескриптор соединения, который далее используется для работы с FTP-сервером.
После установки соединения с FTP-сервером осуществляется регистрация пользователя при помощи функции ftp_login(), имеющей следующий стнтаксис:
bool ftp_login (resource link, string username, string password)
Функция принимает три параметра: дескриптор потока link, возвращаемый функцией ftp_connect(), имя пользователя username и его пароль password. При успешной регистрации на FTP-сервере функция возвращает true, в противном случае —false.
Закрыть FTP-соединение можно при помощи функции ftp_close(), которая имеет следующий синтаксис:
void ftp_close (resource link)
В качестве единственного аргумента link функция принимает дескриптор открытого FTP-соединения.
Примечание. Если доступ осуществляется к анонимному FTP-серверу, то в качестве имени пользователя можно ввести "anonymous", а в качестве пароля — адрес электронной почты.
Соединение с FTP-сервером
<?php
//Адрес FTP-сервера
$ftp_server="ftp.server.ru";
//Пользователь
$ftp_user= "user";
//Пароль
$ftp_password="password";
//задаем время исполнения скрипта, равное 120с
set_time_limit(120);
//Пытаемся установить соединение с FTP-сервером
$link=ftp_connect($ftp_server);
if(!$link) exit ("К сожалению, не удается установить соединение с FTP-сервером $ftp_server");
//Осуществляем регистрацию на сервере
$login= ftp_login($link, $ftp_user, $ftp_password);
//$login=ftp_login($conn_id, $ftp_user, $ftp_password
if(!$login) exit ("К сожалению, не удается зарегистрироваться на сервере. Проверьте регистрационные данные");
?>
Для установки соединения в переменные $ftp_server, $ftp_user, $ftp_password необходимо поместить адрес FTP-сервера, имя пользователя и его пароль соответственно.
Примечание. Для дальнейшей работы с протоколом FTP-код удобно поместить в отдельный файл config_ftp.php, который далее следует подключать ко всем скриптам инструкцией include или require_once, чтобы не переписывать код установки соединения в каждом скрипте.
FTP-сервер может работать под управлением различных операционных систем, каждая из которых имеет свои особенности. Поэтому для дальнейшей работы с ним требуется выяснить тип операционной системы, что осуществляется при помощи функции ftp_systype(), которая имеет следующий синтаксис:
string ftp_systype(resource link)
Функция ftp_systype() принимает единственный параметр link — дескриптор соединения с сервером, возвращаемый функцией ftp_connect(), и возвращает строку с типом операционной системы, например "UNIX" или "Windows".
Функция ftp_systype()
<?php
//Устанавливаем соединение с FTP-сервером
require_once("config_ftp.php");
//Выводим тип операционной системы FTP-сервера
echo ftp_systype($link);
?>
Примечание. В большинстве случаев для работы с FTP-сервером достаточно функций, предоставляемых РНР, но при помощи функции ftp_raw() возможна отправка серверу команд FTP.
После того как получен доступ к ресурсам FTP-сервера, можно начинать работу. Одна из первых задач, которые встают при создании веб-приложений, работающих с сервером — это перемещение по каталогу сервера и получение содержимого каталога. Получить список файлов и подкаталогов текущего каталога можно при помощи функции ftp_rawlist(), имеющей следующий синтаксис:
array ftp_rawlist (resource link, string directory)
В качестве первого параметра функция принимает дескриптор FTP-соединения, а вкачестве второго аргумента — путь к каталогу. Функция возвращает массив строк, каждая из которых содержит информацию о подкаталоге или файле.
Функция ftp_rawlist()
<?php
//Устанавливаем соединение с FTP-сервером
require_once("config_ftp.php");
//Получаем все файлы корневого каталога
$file_list=ftp_rawlist($link, "/");
//Выводим массив $file_list
foreach($file_list as $line) echo $line."<br>";
?>
Результат работы функции
Подстроки -rw-r--r-- и drwxr-xr-x содержат по 10 символов и определяют тип файла и доступ к нему. Первый символ характеризует тип файла:
На практике, при работе с FTP встречаются только первые два вида файлов: каталоги и обычные файлы.
Оставшиеся девять символов определяют режим доступа к файлу или каталогу. При этом подстрока разбивается на три группы, по три символа каждая:
В рамках каждой из этих трех групп существует три вида разрешений:
Таким образом, строка -rw-r--r-- может быть интерпретирована как принадлежащая обычному файлу, для владельца которого установлено право чтения и записи, а для пользователей, входящих в группу владельца файлов, и всех остальных пользователей установлено право только чтения. Строка drwxr-xr-x принадлежит каталогу, для владельца которого установлены все права: чтения, записи и просмотра, а для всех остальных пользователей — только чтения и просмотра.
После этого далее в строке следует число блоков в файле, группа владелец файла или каталога, размер файла в байтах, дата создания и имя файла или каталога.
Информация, возвращаемая функцией ftp_rawlist(), избыточна. Поэтому вместо нее часто используют функцию ftp_nlist(), которая возвращает массив файлов из указанного каталога без дополнительных параметров. Функция имеет следующий синтаксис:
array ftp_nlist(resource link, string directory)
В качестве параметров функция принимает дескриптор FTP-соединения link и имя каталога directory.
Для определения имени текущего каталога предназначена функция ftp_pwd(), которая принимает в качестве единственного параметра дескриптор FTP-соединения link:
string ftp_pwd (resource link)
Изменение текущего каталога на указанный осуществляется при помощи функции ftp_chdir().
Изменение текущего каталога
<?php
//Устанавливаем соединение с FTP-сервером
require_once("config_ftp.php");
//Изменяем текущий каталог
ftp_chdir($link, "logs");
?>
Функция ftp_chdir() имеет два параметра: дескриптор соединения $link и имя нового каталога ($new_dir).
Вернуться на уровень выше можно при помощи функции ftp_cdup(), которая принимает в качестве параметра дескриптор FTP-соединения link:
bool ftp_cdup(resource link)
Функция возвращает true при успешной смене каталога и false в противном случае.
Для работы с каталогами на FTP-сервере предназначена функция ftp_mkdir(), которая имеет следующий синтаксис:
string ftp_mkdir (resource link, string directory)
Функция принимает в качестве первого параметра дескриптор FTP-соединения link, а в качестве второго — имя создаваемого каталога directory. При успешном выполнении функция возвращает имя только что созданного каталога, при неудачном —false.
Создание каталога
<?php
//Устанавливаем соединение с FTP-сервером
require_once("config_ftp.php");
//Создаем каталог new
ftp_mkdir($link,"new");
?>
Для переименования каталога предназначена функция ftp_rename(), которая имеет следующий синтаксис:
boll ftp_rename (resource link, string from, string to)
В качестве первого аргумента функция принимает дескриптор соединения с FTP-сервером, возвращаемый функцией ftp_connect(). Через второй аргумент from передается имя переименованного каталога. В качестве третьего аргумента to выступает новое имя каталога.
Переименование каталога
<?php
//Устанавливаем соединение с FTP-сервером
require_once("config_ftp.php");
//Переименовываем каталог
ftp_rename($link, "new", "old");
?>
Для удаления каталога предназначена функция ftp_rmdir(), имеющая следующий синтаксис:
bool ftp_rmdir(resource link, string directory)
Функция удаляет каталог directory и возвращает true в случае успеха и false в противном случае. Функция удаляет только пустые каталоги.
Удаление каталога
<?php
//Устанавливаем соединение с FTP-сервером
require_once("config_ftp.php");
//Удаляем каталог
ftp_rmdir($link, "old");
?>
Добавление файлов в текущий каталог осуществляется путем загрузки их на FTP-сервер со стороны клиента. Инициализация загрузки файла на FTP-сервер осуществляется функцией ftp_nb_put(), которая имеет следующий синтаксис:
int ftp_nb_put(resource link, string remote_file, string local_file, int mode [, int startpos])
В качестве первого параметра link функция принимает дескриптор соединения с FTP-сервером. Второй аргумент remote_file определяет имя и путь к файлу на удаленном FTP-сервере. Третий параметр local_file определяет путь к локальному файлу. Четвертый параметр mode указывает режим передачи информации: FTP_ASCII для текста и FTP_BINARY для бинарных файлов. Необязательный параметр startpos позволяет задать позицию в байтах, начиная с которой следует загружать файл.
Функция возвращает одну из трех констант:
Если функция возвращает константу FTP_MOREDATA, скрипт ожидает завершения загрузки файла в цикле while. Статус процесса контролируется при помощи функции ftp_nb_continue(), принимающей в качестве единственного параметра дескриптор соединения link, который возвращается функцией ftp_connect(). Функция ftp_nb_continue() возвращает те же самые константы, что и функция ftp_nb_put().
После завершения процесса загрузки файла на FTP-сервер функция ftp_nb_continue() возващает константу FTP_FINISHED и скрипт выходит из цикла while.
Загрузка файла на FTP-сервер
<?php
//Устанавливаем соединение с FTP-сервером
require_once("config_ftp.php");
//Инициируем загрузку файла на FTP-сервер
$ret=ftp_nb_put($link, "phpstage68.html", "D:\sevidi\phpstage68.html", FTP_BINARY);
//Цикл загрузки
while($ret==FTP_MOREDATA)
{
//Выводим точки, чтобы пользователь знал,
//что процесс загрузки идет
echo ".";
//Продолжаем загрузку
$ret=ftp_nb_continue($link);
}
if ($ret!=FTP_FINISHED)
exit("<br> Во время загрузки файла произошла ошибка ...");
?>
За переименование файлов на FTP-сервере несет ответственность функция ftp_rename(), которая имеет следующий синтаксис:
boll ftp_rename (resource link, string from, string to)
Удаление файла осуществляется при помощи функции ftp_delete(), которая принимает в качестве первого аргумента дескриптор соединения с FTP-сервером, а в качестве второго — путь к удаленному файлу. В случае успешного удаления файла функция возвращает true, иначе —false.
Удаление файла с FTP-сервера
<?php
//Устанавливаем соединение с FTP-сервером
require_once("config_ftp.php");
//Удаление файла
ftp_delete($link, "phpstage68.html");
?>
Загрузка файлов с FTP-сервера осуществляется функцией ftp_nb_get(), которая имеет следующий синтаксис:
int ftp_nb_get((resource link, string local_file, string remote_file, int mode [, int resumepos])
В качестве первого параметра link функция принимает дескриптор соединения с FTP-сервером. Второй аргумент local_file определяет путь к локальному файлу. Третий параметр remote_file указывает путь к файлу на удаленном FTP-сервере. Четвертый параметр mode определяет режим передачи информации: Необязательный параметр resumepos позволяет задать позицию в байтах, начиная с которой следует загружать файл.
Функция возвращает одну из трех констант:
Контроль за состоянием загрузки файла осуществляется в цикле while при помощи рассмотренной выше функции ftp_nb_continue().
Загрузка файлов с FTP-сервера
<?php
//Устанавливаем соединение с FTP-сервером
require_once("config_ftp.php");
//Инициализируем загрузку файла с FTP-сервера
$ret=ftp_nb_get($link, "D:\sevidi\phpstage68.html", "phpstage68.html", FTP_BINARY);
//Цикл загрузки
while($ret==FTP_MOREDATA)
{
//Выводим точки, чтобы пользователь знал,
//что процесс загрузки идет
echo ".";
//Продолжаем загрузку
$ret=ftp_nb_continue($link);
}
//Если произошла ошибка при загрузке файла,
//уведомляем об этом пользователя
if ($ret!=FTP_FINISHED)
exit("<br> Во время загрузки файла произошла ошибка ...");
?>
Кроме рассмотренной ранее, текстовой формы задания прав доступа в операционной системе UNIX, права доступа можно задать восьмеричным числом. При этом праву чтения соответствует цифра 4, праву записи — 2, а исполнению — 1. Общие права для групп задаются суммой этих чисел. Так значение 6 (4+2) обеспечивает возможность чтения и записи, а значение 7(4+2+1) предоставляет полный доступ к файлу или каталогу. Тогда для каталога восьмеричное число 0755 означает, что владелец каталога имеет полный доступ (rwx), а все остальные — право читать файлы в нем и просматривать содержимое каталога (r-x).
Примечание. В РНР восьмеричные числа предваряются нулем.
Права доступа для файлов и каталогов устанавливаются при помощи функции ftp_chmod(), которая имеет следующий синтаксис:
string ftp_chmod (resource link, int mode, string directory)
В качестве первого аргумента link эта функция, так же как и большинство другихфункций для работы с FTP, принимает дескриптор соединения, возвращаемый функцией ftp_connect(). Второй параметр mode принимает восьмеричное число, задающее права доступа к каталогу. Последний параметр directory определяет имя каталога, права доступа к которому изменяются. Функция возвращает только что установленные права в случае успеха и false в противном случае.
Установка прав доступа к каталогам и файлам
<?php
//Устанавливаем соединение с FTP-сервером
require_once("config_ftp.php");
//Устанавливаем права доступа к каталогу
ftp_chmod ($link, 0755, "lods");
//Устанавливаем права доступа к файлу
ftp_chmod ($link, 0755, "/path/file.php");
?>