ftp_pasv()
A função ftp_pasv() é uma função PHP integrada que ativa o modo passivo para a conexão FTP. Neste artigo, discutimos a função em detalhes.
A Função PHP ftp_pasv()
A função ftp_pasv() ativa ou desativa o modo passivo em uma conexão FTP aberta. O modo passivo controla qual lado abre o canal de dados durante uma transferência, e acertar isso é a correção mais comum quando downloads FTP e listagens de diretório ficam travados ou expiram. Este capítulo explica o que é o modo passivo, quando você precisa dele e como chamar ftp_pasv() corretamente em um script de transferência real.
Modo ativo vs. modo passivo
O FTP usa dois canais separados: um canal de comando (onde você envia LIST, RETR, etc.) e um canal de dados (onde fluem os bytes do arquivo ou a listagem). Os dois modos diferem apenas em quem abre o canal de dados:
- Modo ativo (padrão no protocolo): o servidor abre a conexão de dados de volta para o cliente. Se o cliente estiver atrás de um firewall ou roteador NAT, essa conexão de entrada normalmente é bloqueada, fazendo a transferência travar.
- Modo passivo: o cliente abre ambos os canais para o servidor. Como o cliente só faz conexões de saída, funciona com quase qualquer configuração de firewall ou NAT.
Por isso o modo passivo é o padrão seguro para a maioria dos scripts modernos: os clientes estão quase sempre atrás de NAT, enquanto os servidores são acessíveis em um endereço público.
Sintaxe
ftp_pasv(FTP\Connection $ftp, bool $passive): bool$ftp— a conexão FTP retornada porftp_connect(). A partir do PHP 8.1, isso é um objetoFTP\Connection; no PHP 8.0 e anteriores era um resource. O código existente continua funcionando de qualquer forma.$passive—truepara ativar o modo passivo,falsepara voltar ao modo ativo.
A função retorna true em caso de sucesso e false em caso de falha.
A ordem importa: chame
ftp_pasv()apósftp_login()e antes de qualquer transferência comoftp_get(),ftp_put()ouftp_nlist(). Chamá-la antes do login falha porque o modo passivo é negociado dentro de uma sessão autenticada.
Uma transferência completa em modo passivo
O exemplo abaixo conecta, faz login, alterna para o modo passivo, baixa um arquivo e realiza a limpeza. Cada etapa verifica seu valor de retorno para que as falhas sejam relatadas em vez de silenciosamente ignoradas.
<?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);Sem a linha ftp_pasv($ftp, true), o passo 4 frequentemente travaria atrás de um roteador NAT porque o servidor não conseguiria abrir a conexão de dados de entrada.
Tratamento de falhas
ftp_pasv() retorna false quando o servidor recusa a mudança de modo ou a conexão não é mais válida. Sempre verifique o valor de retorno antes de tentar uma transferência e use ftp_close() para liberar a conexão em todos os caminhos de saída:
<?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
}Quando usar o modo ativo
O modo passivo se encaixa na maioria dos clientes, mas algumas situações exigem o modo ativo (ftp_pasv($ftp, false)):
- O intervalo de portas passivas do servidor está bloqueado pelo firewall, então as conexões de dados passivas são recusadas enquanto as ativas têm sucesso.
- Você está conectando de um host com IP público e sem restrições de entrada, falando com um servidor que só permite transferências ativas.
Se uma transferência travar, alternar o modo é a primeira coisa a tentar — muitos relatórios de "FTP está quebrado" são simplesmente o modo errado para a rede.
Conclusão
ftp_pasv() decide se o cliente ou o servidor abre o canal de dados FTP. Ative-o (true) para clientes atrás de firewalls ou NAT — o que é a maioria das vezes — e chame-o logo após ftp_login() e antes de qualquer transferência. Verificar seu valor de retorno e fechar a conexão com ftp_close() mantém seus scripts FTP confiáveis em diferentes configurações de rede.