W3docs

ftp_nb_continue()

Функция ftp_nb_continue() — встроенная функция PHP для продолжения асинхронной FTP-операции. Принимает один параметр.

Что такое ftp_nb_continue()?

ftp_nb_continue() — встроенная функция PHP, которая возобновляет — или продолжаетнеблокирующую передачу файлов по FTP, начатую ранее. Аббревиатура nb в названии расшифровывается как non-blocking (неблокирующий): вместо того чтобы останавливать выполнение скрипта до завершения загрузки или скачивания всего файла, неблокирующие FTP-функции возвращают управление после каждого фрагмента, позволяя скрипту выполнять другие задачи в промежутках.

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

Как работают неблокирующие передачи

Обычная передача, например ftp_get(), является блокирующей: PHP ожидает полной загрузки файла перед переходом к следующей строке. Семейство неблокирующих функций — ftp_nb_get(), ftp_nb_put(), ftp_nb_fget() и ftp_nb_fput()начинает передачу и сразу возвращает управление. Затем вы вызываете ftp_nb_continue() многократно, продвигая передачу на один фрагмент за раз, пока функция не сообщит о завершении.

Функция возвращает одну из трёх констант:

КонстантаЗначение
FTP_MOREDATAПередача ещё продолжается — вызовите ftp_nb_continue() снова.
FTP_FINISHEDПередача успешно завершена — остановите цикл.
FTP_FAILEDПередача завершилась с ошибкой — обработайте ошибку и остановитесь.

Примечание: стартовая функция (ftp_nb_get() и т. д.) возвращает тот же набор констант, поэтому логика вашего цикла должна учитывать возможность завершения передачи уже при первом вызове.

Синтаксис ftp_nb_continue()

ftp_nb_continue(resource $ftp): int

Функция принимает единственный параметр — $ftp: идентификатор соединения, возвращённый функцией ftp_connect() или ftp_ssl_connect().

PHP 8.1+: соединение теперь представлено объектом FTP\Connection вместо resource, однако ваш код изменять не нужно — вы по-прежнему передаёте значение, полученное от ftp_connect().

Использование ftp_nb_continue()

Сначала запустите неблокирующую передачу, затем доведите её до завершения с помощью цикла:

<?php

// Open the connection and log in
$ftp = ftp_connect('ftp.example.com');
ftp_login($ftp, 'username', 'password');
ftp_pasv($ftp, true); // passive mode is usually required behind firewalls

// Start a non-blocking download: local_file <- remote_file
$state = ftp_nb_get($ftp, 'local_file.txt', 'remote_file.txt', FTP_BINARY);

// Drive the transfer forward until it finishes or fails
while ($state === FTP_MOREDATA) {
    // You can do other work here while the file streams in
    $state = ftp_nb_continue($ftp);
}

if ($state === FTP_FINISHED) {
    echo "Download complete.\n";
} else {
    echo "Download failed.\n";
}

ftp_close($ftp);

Обратите внимание на порядок аргументов ftp_nb_get(): это (соединение, локальный_файл, удалённый_файл, режим)локальный путь назначения указывается перед удалённым источником.

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

Всегда проверяйте возвращаемое значение на каждой итерации. Если ftp_nb_continue() возвращает FTP_FAILED, передача прервалась — следует остановиться и сообщить об ошибке, а не зациклиться бесконечно:

<?php

$state = ftp_nb_get($ftp, 'local_file.txt', 'remote_file.txt', FTP_BINARY);

while ($state === FTP_MOREDATA) {
    $state = ftp_nb_continue($ftp);
}

switch ($state) {
    case FTP_FINISHED:
        echo "Transfer succeeded.\n";
        break;
    case FTP_FAILED:
        echo "Transfer failed.\n";
        break;
}

Поскольку условие цикла — === FTP_MOREDATA, цикл автоматически завершается как при FTP_FINISHED, так и при FTP_FAILED — последующий switch сообщает, что именно произошло.

Типичные ловушки

  • Отсутствие проверки возвращаемого значения стартовой функции. Небольшой файл может полностью загрузиться во время выполнения ftp_nb_get(), вернув FTP_FINISHED ещё до запуска цикла. Присвоение возвращаемого значения переменной $state (как показано выше) корректно обрабатывает этот случай.
  • Вызов ftp_nb_continue() без активной передачи. Функция работает только тогда, когда неблокирующая операция находится в процессе выполнения; в противном случае она возвращает FTP_FAILED.
  • Пустой «жёсткий» цикл. Весь смысл неблокирующего FTP — выполнять полезную работу между вызовами. Пустой цикл while просто бесполезно занимает процессор и не даёт никакого преимущества перед блокирующим ftp_get().
  • Пассивный режим. За брандмауэром или NAT обычно необходимо вызвать ftp_pasv() с параметром true до начала передачи.

Заключение

ftp_nb_continue() возобновляет неблокирующую FTP-передачу, начатую функциями ftp_nb_get(), ftp_nb_put(), ftp_nb_fget() или ftp_nb_fput(). Вызывайте её в цикле, пока она возвращает FTP_MOREDATA, останавливайтесь при FTP_FINISHED и обрабатывайте FTP_FAILED — тогда ваш скрипт останется отзывчивым, пока файлы передаются в фоновом режиме.

Практика

Практика
Какова основная функция FTP_NB_CONTINUE в PHP?
Какова основная функция FTP_NB_CONTINUE в PHP?
Was this page helpful?