W3docs

ftp_nb_continue()

The ftp_nb_continue() function is a PHP built-in function that continues an asynchronous FTP operation. The function takes one parameter:

What is ftp_nb_continue()?

ftp_nb_continue() is a built-in PHP function that resumes — or continues — a non-blocking FTP file transfer that was started earlier. The nb in the name stands for non-blocking: instead of freezing your script until a whole file is uploaded or downloaded, the non-blocking FTP functions return control after each chunk so your script can do other work in between.

This page covers what the function returns, how the non-blocking transfer loop works, how to handle errors, and the common pitfalls.

How non-blocking transfers work

A normal transfer such as ftp_get() blocks: PHP waits for the entire file before the next line runs. The non-blocking family — ftp_nb_get(), ftp_nb_put(), ftp_nb_fget() and ftp_nb_fput()starts the transfer and returns immediately. You then call ftp_nb_continue() repeatedly to move the transfer forward one chunk at a time, until it reports it is finished.

The function returns one of three constants:

ConstantMeaning
FTP_MOREDATAThe transfer is still in progress — call ftp_nb_continue() again.
FTP_FINISHEDThe transfer completed successfully — stop the loop.
FTP_FAILEDThe transfer failed — handle the error and stop.

Note: the start function (ftp_nb_get() etc.) returns the same set of constants, so your loop logic must account for the transfer finishing on the very first call.

Syntax of ftp_nb_continue()

ftp_nb_continue(resource $ftp): int

It takes a single parameter, $ftp: the connection identifier returned by ftp_connect() or ftp_ssl_connect().

PHP 8.1+: the connection is now an FTP\Connection object instead of a resource, but your code does not need to change — you still just pass the value you got back from ftp_connect().

Using ftp_nb_continue()

You first start a non-blocking transfer, then drive it to completion with a loop:

<?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);

Note the argument order of ftp_nb_get(): it is (connection, local_file, remote_file, mode) — the local destination comes before the remote source.

Error handling

Always check the return value on every iteration. If ftp_nb_continue() returns FTP_FAILED, the transfer broke and you should stop and report it rather than loop forever:

<?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;
}

Because the loop condition is === FTP_MOREDATA, it exits automatically on both FTP_FINISHED and FTP_FAILED — the switch afterwards then tells you which one happened.

Common pitfalls

  • Forgetting to check the start function's return value. A small file can finish during ftp_nb_get() itself, returning FTP_FINISHED before the loop ever runs. Assigning that return value to $state (as above) handles this correctly.
  • Calling ftp_nb_continue() with no active transfer. It only works while a non-blocking operation is pending; otherwise it returns FTP_FAILED.
  • A tight, empty loop. The whole point of non-blocking FTP is to do useful work between calls. An empty while loop just busy-waits and gives you no advantage over the blocking ftp_get().
  • Passive mode. Behind a firewall or NAT you usually need ftp_pasv() set to true before starting the transfer.

Conclusion

ftp_nb_continue() resumes a non-blocking FTP transfer that was started with ftp_nb_get(), ftp_nb_put(), ftp_nb_fget() or ftp_nb_fput(). Call it in a loop while it returns FTP_MOREDATA, stop on FTP_FINISHED, and handle FTP_FAILED — and your script stays responsive while files move in the background.

Practice

Practice
What is the main function of the FTP_NB_CONTINUE in PHP?
What is the main function of the FTP_NB_CONTINUE in PHP?
Was this page helpful?