W3docs

ftp_pasv()

Функция ftp_pasv() в PHP включает пассивный режим для FTP-соединения. В этой статье подробно рассматривается её использование.

Функция PHP ftp_pasv()

Функция ftp_pasv() включает или отключает пассивный режим для открытого FTP-соединения. Пассивный режим определяет, какая сторона открывает канал данных во время передачи, и его правильная настройка — наиболее распространённое решение, когда загрузки FTP и просмотр каталогов зависают или завершаются по таймауту. В этой главе объясняется, что такое пассивный режим, когда он нужен и как правильно вызывать ftp_pasv() в реальном скрипте передачи файлов.

Активный и пассивный режим

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

  • Активный режим (по умолчанию в протоколе): сервер открывает соединение данных обратно к клиенту. Если клиент находится за межсетевым экраном или NAT-маршрутизатором, это входящее соединение обычно блокируется, и передача зависает.
  • Пассивный режим: клиент открывает оба канала к серверу. Поскольку клиент всегда устанавливает только исходящие соединения, этот режим работает практически при любых настройках межсетевого экрана или NAT.

Именно поэтому пассивный режим является безопасным режимом по умолчанию для большинства современных скриптов: клиенты почти всегда находятся за NAT, тогда как серверы доступны по публичному адресу.

Синтаксис

ftp_pasv(FTP\Connection $ftp, bool $passive): bool
  • $ftp — FTP-соединение, возвращённое функцией ftp_connect(). Начиная с PHP 8.1 это объект FTP\Connection; в PHP 8.0 и более ранних версиях — ресурс. Существующий код продолжит работать в любом случае.
  • $passivetrue для включения пассивного режима, false для возврата в активный режим.

Функция возвращает true при успехе и false при сбое.

Порядок вызова важен: вызывайте ftp_pasv() после ftp_login() и до любой передачи, такой как ftp_get(), ftp_put() или ftp_nlist(). Вызов до входа в систему завершится ошибкой, так как пассивный режим согласовывается в рамках аутентифицированного сеанса.

Полная передача в пассивном режиме

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

<?php

// 1. Connect to the FTP server (30-second timeout)
$ftp = ftp_connect('ftp.example.com', 21, 30);
if (!$ftp) {
    die("Could not connect to the FTP server.\n");
}

// 2. Authenticate
if (!ftp_login($ftp, 'username', 'password')) {
    ftp_close($ftp);
    die("FTP login failed.\n");
}

// 3. Switch to passive mode — must come after login, before any transfer
if (!ftp_pasv($ftp, true)) {
    ftp_close($ftp);
    die("Could not switch to passive mode.\n");
}

// 4. Download a file now that the data channel will be client-initiated
if (ftp_get($ftp, 'local-copy.txt', 'remote/report.txt', FTP_BINARY)) {
    echo "File downloaded successfully.\n";
} else {
    echo "File download failed.\n";
}

// 5. Always close the connection
ftp_close($ftp);

Без строки ftp_pasv($ftp, true) шаг 4 часто зависал бы за NAT-маршрутизатором, поскольку сервер не смог бы открыть входящее соединение данных.

Обработка ошибок

ftp_pasv() возвращает false, если сервер отклоняет смену режима или соединение более не действительно. Всегда проверяйте возвращаемое значение перед попыткой передачи и используйте ftp_close() для освобождения соединения при каждом пути выхода:

<?php

if (!ftp_pasv($ftp, true)) {
    echo "Failed to enable passive mode on the remote server.\n";
    ftp_close($ftp);
    return; // stop before attempting a transfer that would stall
}

Когда использовать активный режим

Пассивный режим подходит для большинства клиентов, но в ряде ситуаций требуется активный режим (ftp_pasv($ftp, false)):

  • Диапазон портов пассивного режима на сервере закрыт межсетевым экраном, поэтому пассивные соединения данных отклоняются, тогда как активные работают.
  • Подключение выполняется с хоста с публичным IP без входящих ограничений, а сервер разрешает только активные передачи.

Если передача зависает, переключение режима — первое, что стоит попробовать: многие жалобы на «сломанный FTP» объясняются просто неправильным режимом для данной сети.

Заключение

ftp_pasv() определяет, кто открывает канал данных FTP — клиент или сервер. Включайте его (true) для клиентов за межсетевыми экранами или NAT — что является нормой в большинстве случаев — и вызывайте сразу после ftp_login() и до любой передачи. Проверка возвращаемого значения и закрытие соединения с помощью ftp_close() обеспечат надёжную работу FTP-скриптов в различных сетевых конфигурациях.

Практика

Практика
Что делает функция pasv() в FTP при использовании PHP?
Что делает функция pasv() в FTP при использовании PHP?
Was this page helpful?