Current Location: Home> Latest Articles> ftp_nb_continue Keeps Hanging? Try These Fixes to Avoid Blocking and Timeout Issues

ftp_nb_continue Keeps Hanging? Try These Fixes to Avoid Blocking and Timeout Issues

gitbox 2025-06-09

When using PHP's non-blocking FTP function ftp_nb_continue(), many developers encounter a frustrating issue: the program appears to "hang" — it neither throws an error nor continues execution. This often happens because the FTP session has entered an unexpected wait state. This article explores the common causes behind ftp_nb_continue() hanging and offers practical solutions to help you avoid blocking and timeout problems.

What is ftp_nb_continue?

ftp_nb_continue() is used in conjunction with non-blocking transfer functions such as ftp_nb_get() and ftp_nb_put(). Its purpose is to continue an incomplete FTP operation. The benefit of non-blocking transfers is that you can handle other logic while waiting for a transfer to complete, improving program responsiveness.

A typical non-blocking download process looks like this:

$ftp = ftp_connect('gitbox.net'); ftp_login($ftp, 'username', 'password'); $ret = ftp_nb_get($ftp, 'local_file.txt', 'remote_file.txt', FTP_BINARY);

while ($ret == FTP_MOREDATA) {
// Perform other tasks
do_something_else();

// Continue transfer
$ret = ftp_nb_continue($ftp);

}

Looks pretty straightforward, right? But in practice, many users find themselves stuck in this loop.

Common Reasons It Gets Stuck

1. Slow or Unresponsive FTP Server

Some FTP servers respond slowly under certain conditions, especially when large files are requested or network quality is poor. This can cause ftp_nb_continue() to remain in the FTP_MOREDATA state indefinitely.

Solution:

  • Set a reasonable timeout:

    ftp_set_option($ftp, FTP_TIMEOUT_SEC, 30);
  • Use stream_set_timeout() for more granular control (requires access to the underlying stream of the FTP connection).

2. No Delay in Loop, Causing High CPU Usage

Many developers forget to include a delay in their non-blocking loop, leading to high CPU usage and overwhelming the FTP server, which cannot respond in time.

Solution:

while ($ret == FTP_MOREDATA) { do_something_else(); usleep(100000); // Delay for 100ms $ret = ftp_nb_continue($ftp); }

3. File Transfer Completes But State Doesn't Update

Some FTP servers do not return the correct status code after completing a transfer, causing ftp_nb_continue() to think the transfer is still in progress.

Solution:

  • Check if the local file has reached the expected size;

  • Set a maximum number of retries:

    $maxTries = 100; $tries = 0;

    while ($ret == FTP_MOREDATA && $tries < $maxTries) {
    usleep(100000);
    $ret = ftp_nb_continue($ftp);
    $tries++;
    }

    if ($tries == $maxTries) {
    throw new Exception('FTP transfer timed out');
    }

4. Incorrect Passive/Active Mode Settings

Different servers handle active (PORT) and passive (PASV) modes differently. Incorrect configuration can result in a connection being established but data transfer failing.

Solution:

ftp_pasv($ftp, true); // Enable passive mode

Try switching between active and passive modes to see which works better with your FTP server.

Best Practices Summary

  • Always implement an exit mechanism in non-blocking loops;

  • Ensure appropriate delays are included in loops;

  • Set timeouts and maximum retry limits;

  • If transfer hangs for too long, try switching FTP modes;

  • Don't forget to release resources:

    ftp_close($ftp);

Conclusion

ftp_nb_continue() can significantly improve the flexibility of FTP operations in PHP, but it’s also easy to run into trouble. With the techniques outlined above, you can avoid common pitfalls like blocking, infinite loops, and excessive CPU usage, making your PHP FTP programs more robust and efficient. If you're experiencing similar issues, try diagnosing them one by one and apply the appropriate fix accordingly.