ftp_nb_continue()
A função ftp_nb_continue() é uma função nativa do PHP que continua uma operação FTP assíncrona. A função recebe um parâmetro:
O que é ftp_nb_continue()?
ftp_nb_continue() é uma função nativa do PHP que retoma — ou continua — uma transferência de arquivo FTP não bloqueante iniciada anteriormente. O nb no nome significa non-blocking (não bloqueante): em vez de congelar o script até que todo um arquivo seja enviado ou recebido, as funções FTP não bloqueantes devolvem o controle após cada fragmento para que o script possa executar outras tarefas no intervalo.
Esta página aborda o que a função retorna, como funciona o laço de transferência não bloqueante, como tratar erros e as armadilhas mais comuns.
Como funcionam as transferências não bloqueantes
Uma transferência normal como ftp_get() bloqueia: o PHP aguarda o arquivo completo antes de executar a próxima linha. A família não bloqueante — ftp_nb_get(), ftp_nb_put(), ftp_nb_fget() e ftp_nb_fput() — inicia a transferência e retorna imediatamente. Em seguida, você chama ftp_nb_continue() repetidamente para avançar a transferência um fragmento de cada vez, até que ela sinalize que terminou.
A função retorna uma das três constantes:
| Constante | Significado |
|---|---|
FTP_MOREDATA | A transferência ainda está em andamento — chame ftp_nb_continue() novamente. |
FTP_FINISHED | A transferência foi concluída com sucesso — encerre o laço. |
FTP_FAILED | A transferência falhou — trate o erro e encerre. |
Nota: a função de início (
ftp_nb_get()etc.) retorna o mesmo conjunto de constantes, portanto a lógica do seu laço deve considerar que a transferência pode terminar já na primeira chamada.
Sintaxe de ftp_nb_continue()
ftp_nb_continue(resource $ftp): intEla aceita um único parâmetro, $ftp: o identificador de conexão retornado por ftp_connect() ou ftp_ssl_connect().
PHP 8.1+: a conexão agora é um objeto
FTP\Connectionem vez de umresource, mas o seu código não precisa mudar — você ainda apenas passa o valor obtido deftp_connect().
Usando ftp_nb_continue()
Primeiro você inicia uma transferência não bloqueante e depois a conduz até o fim com um laço:
<?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);Observe a ordem dos argumentos de ftp_nb_get(): é (connection, local_file, remote_file, mode) — o destino local vem antes da origem remota.
Tratamento de erros
Sempre verifique o valor de retorno em cada iteração. Se ftp_nb_continue() retornar FTP_FAILED, a transferência falhou e você deve interromper e reportar o erro em vez de entrar em loop infinito:
<?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;
}Como a condição do laço é === FTP_MOREDATA, ele sai automaticamente tanto em FTP_FINISHED quanto em FTP_FAILED — o switch a seguir informa qual ocorreu.
Armadilhas comuns
- Esquecer de verificar o valor de retorno da função de início. Um arquivo pequeno pode terminar durante a própria
ftp_nb_get(), retornandoFTP_FINISHEDantes de o laço sequer executar. Atribuir esse valor de retorno a$state(como acima) trata isso corretamente. - Chamar
ftp_nb_continue()sem uma transferência ativa. Ela só funciona enquanto uma operação não bloqueante está pendente; caso contrário, retornaFTP_FAILED. - Um laço vazio e fechado. O objetivo das funções FTP não bloqueantes é executar trabalho útil entre as chamadas. Um laço
whilevazio apenas fica em espera ocupada e não oferece nenhuma vantagem sobre o bloqueanteftp_get(). - Modo passivo. Atrás de um firewall ou NAT, geralmente é necessário definir
ftp_pasv()comotrueantes de iniciar a transferência.
Conclusão
ftp_nb_continue() retoma uma transferência FTP não bloqueante iniciada com ftp_nb_get(), ftp_nb_put(), ftp_nb_fget() ou ftp_nb_fput(). Chame-a em um laço enquanto ela retornar FTP_MOREDATA, pare em FTP_FINISHED e trate FTP_FAILED — e seu script permanecerá responsivo enquanto os arquivos são transferidos em segundo plano.