W3docs

PHP FTP

FTP в PHP позволяет подключаться к удалённым серверам, загружать и скачивать файлы, управлять директориями с помощью встроенного расширения ext-ftp.

Введение

FTP (File Transfer Protocol) — стандартный сетевой протокол для передачи файлов между клиентом и сервером по TCP-соединению. PHP поставляется со встроенным расширением FTP (ext-ftp), которое позволяет скриптам входить на удалённый сервер и перемещать файлы программно — это удобно для развёртывания ресурсов, синхронизации резервных копий или получения потоков данных с сервера партнёра.

В этой главе рассматривается полный рабочий процесс: подключение, вход в систему, переключение в пассивный режим, загрузка и скачивание файлов, просмотр удалённых файлов и управление ими, а также корректное закрытие соединения. Также объясняются меры безопасности, которые необходимо учитывать перед использованием обычного FTP в производственной среде.

Прежде всего о безопасности. Обычный FTP передаёт имя пользователя, пароль и содержимое файлов в незашифрованном виде. Для конфиденциальных данных используйте ftp_ssl_connect() (FTP поверх TLS) или предпочтите SFTP (SSH File Transfer Protocol), который расширение FTP не поддерживает — для SFTP используйте расширение PHP SSH2 или библиотеку, например phpseclib.

Типичный рабочий процесс FTP

Каждый FTP-скрипт следует одной и той же структуре, независимо от выполняемой операции:

  1. Подключение к серверу — ftp_connect() (или ftp_ssl_connect() для FTPS).
  2. Аутентификацияftp_login().
  3. Настройка — обычно ftp_pasv($conn, true) для включения пассивного режима.
  4. Передача / управление файлами — ftp_put(), ftp_get(), ftp_nlist() и др.
  5. Закрытиеftp_close().

Подключение к FTP-серверу

Установите соединение с помощью ftp_connect(). Функция принимает имя хоста (а также необязательные порт и таймаут) и возвращает объект FTP\Connection при успехе (ресурс до PHP 8.1) или false при ошибке.

<?php

$conn = ftp_connect("ftp.example.com", 21, 10); // host, port, timeout (seconds)
if ($conn === false) {
    die("Could not connect to FTP server");
}
echo "Connected.";

Обратите внимание, что подключение не выполняет вход — на этом этапе у вас есть анонимный, неаутентифицированный канал. Перед тем как сервер разрешит выполнять какие-либо полезные действия, необходимо вызвать ftp_login().

Использование FTPS (FTP поверх TLS)

Для шифрования управляющего и информационного каналов замените ftp_connect() на ftp_ssl_connect(). Остальная часть API идентична:

<?php

$conn = ftp_ssl_connect("ftp.example.com");
if ($conn === false) {
    die("Could not open a secure FTP connection");
}

Вход в систему и пассивный режим

После подключения выполните аутентификацию с помощью ftp_login(). Для публичных серверов, допускающих анонимный доступ, используйте имя пользователя anonymous с паролем в виде адреса электронной почты.

<?php

$conn = ftp_connect("ftp.example.com");

if (!ftp_login($conn, "username", "password")) {
    ftp_close($conn);
    die("Login failed");
}

// Most networks behind a firewall/NAT require passive mode.
ftp_pasv($conn, true);

echo "Logged in.";

Почему важен пассивный режим. В активном режиме сервер открывает соединение данных обратно к вашему клиенту, что межсетевые экраны и NAT-маршрутизаторы почти всегда блокируют. В пассивном режиме клиент сам открывает соединение данных с сервером, что работает за межсетевыми экранами. Как правило, вызывайте ftp_pasv($conn, true) сразу после входа. Его необходимо устанавливать после ftp_login(), а не до.

Загрузка файлов

Используйте ftp_put() для отправки локального файла на сервер. Сигнатура функции: ftp_put($conn, $remote_file, $local_file, $mode), где $mode — это FTP_BINARY или FTP_ASCII.

<?php

$conn = ftp_connect("ftp.example.com");
ftp_login($conn, "username", "password");
ftp_pasv($conn, true);

if (ftp_put($conn, "/public_html/report.pdf", "report.pdf", FTP_BINARY)) {
    echo "Upload successful";
} else {
    echo "Upload failed";
}

ftp_close($conn);

FTP_BINARY или FTP_ASCII. Используйте FTP_BINARY для всего, что не является простым текстом — изображений, PDF-файлов, архивов, исполняемых файлов — поскольку ASCII-режим перезаписывает окончания строк и повредит бинарные данные. Используйте FTP_ASCII только тогда, когда специально требуется преобразование окончаний строк между платформами для текстовых файлов. В сомнительных случаях выбирайте FTP_BINARY — это безопасный вариант по умолчанию.

Для больших файлов можно загружать в неблокирующем режиме с помощью ftp_nb_put(), что позволяет скрипту выполнять другую работу между фрагментами.

Скачивание файлов

ftp_get() сохраняет удалённый файл в локальную файловую систему. Порядок аргументов: ftp_get($conn, $local_file, $remote_file, $mode) — обратите внимание, что локальный путь назначения указывается первым, в отличие от ftp_put(). Путаница с этим — самая распространённая ошибка при работе с FTP.

<?php

$conn = ftp_connect("ftp.example.com");
ftp_login($conn, "username", "password");
ftp_pasv($conn, true);

// local_file first, then remote_file
if (ftp_get($conn, "backup.zip", "/backups/backup.zip", FTP_BINARY)) {
    echo "Download successful";
} else {
    echo "Download failed";
}

ftp_close($conn);

Просмотр удалённых файлов и управление ими

Расширение FTP умеет гораздо больше, чем просто передавать файлы. К распространённым функциям управления относятся:

ФункцияНазначение
ftp_nlist($conn, $dir)Массив имён файлов в директории
ftp_rawlist($conn, $dir)Детальный листинг в стиле ls -l
ftp_size($conn, $file)Размер файла в байтах (-1 при ошибке)
ftp_mkdir($conn, $dir)Создать директорию
ftp_rmdir($conn, $dir)Удалить (пустую) директорию
ftp_delete($conn, $file)Удалить файл
ftp_rename($conn, $from, $to)Переименовать / переместить файл
ftp_chdir($conn, $dir)Изменить рабочую директорию
ftp_pwd($conn)Текущая рабочая директория
ftp_chmod($conn, 0644, $file)Изменить права доступа к файлу
<?php

$conn = ftp_connect("ftp.example.com");
ftp_login($conn, "username", "password");
ftp_pasv($conn, true);

$files = ftp_nlist($conn, "/public_html");
foreach ($files as $file) {
    echo $file, " — ", ftp_size($conn, $file), " bytes\n";
}

ftp_close($conn);

Закрытие соединения

Всегда освобождайте соединение с помощью ftp_close() по завершении работы. Оборачивание рабочего процесса в try/finally гарантирует закрытие сокета даже при возникновении ошибки:

<?php

$conn = ftp_connect("ftp.example.com");
if (!$conn || !ftp_login($conn, "username", "password")) {
    die("Connection or login failed");
}

try {
    ftp_pasv($conn, true);
    ftp_put($conn, "/public_html/index.html", "index.html", FTP_BINARY);
} finally {
    ftp_close($conn);
}

Рекомендации и подводные камни

  • Предпочитайте FTPS или SFTP. Никогда не передавайте учётные данные через обычный FTP через публичный интернет.
  • Всегда включайте пассивный режим (ftp_pasv), если нет особых причин не делать этого.
  • Выбирайте правильный режим передачиFTP_BINARY для бинарных данных, FTP_ASCII только для текста, где необходимо преобразование окончаний строк.
  • Следите за порядком аргументов — в ftp_put порядок (remote, local), в ftp_get(local, remote).
  • Всегда закрывайте соединение с помощью ftp_close().
  • Проверяйте каждое возвращаемое значение. Функции FTP возвращают false при ошибке, а не бросают исключения, поэтому тихие сбои легко пропустить.
  • ext-ftp должно быть включено. Проверьте с помощью extension_loaded('ftp'); если возвращается false, включите расширение в вашем php.ini.

Связанные темы

Практика

Практика
Каковы функции FTP в PHP?
Каковы функции FTP в PHP?
Was this page helpful?