PHP FTP
FTP em PHP permite transferir arquivos entre cliente e servidor. Saiba como conectar, autenticar, enviar e receber arquivos com a extensão ext-ftp.
Introdução
FTP (File Transfer Protocol) é um protocolo de rede padrão para transferir arquivos entre um cliente e um servidor por meio de uma conexão TCP. O PHP inclui uma extensão FTP integrada (ext-ftp) que permite aos seus scripts fazer login em um servidor remoto e mover arquivos de forma programática — útil para implantar recursos, sincronizar backups ou baixar feeds de dados do servidor de um parceiro.
Este capítulo abrange o fluxo de trabalho completo: conectar, fazer login, alternar para o modo passivo, fazer upload e download, listar e gerenciar arquivos remotos e, por fim, fechar a conexão de forma limpa. Ele também explica as ressalvas de segurança que você deve conhecer antes de usar FTP simples em produção.
Nota de segurança primeiro. O FTP simples envia seu nome de usuário, senha e conteúdo de arquivos sem criptografia. Para qualquer coisa sensível, use
ftp_ssl_connect()(FTP sobre TLS) ou prefira SFTP (SSH File Transfer Protocol), que a extensão FTP não suporta — use a extensão PHP SSH2 ou uma biblioteca como phpseclib para SFTP.
O fluxo de trabalho típico do FTP
Todo script FTP segue a mesma estrutura, independentemente da operação realizada:
- Conectar ao servidor —
ftp_connect()(ouftp_ssl_connect()para FTPS). - Autenticar —
ftp_login(). - Configurar — geralmente
ftp_pasv($conn, true)para habilitar o modo passivo. - Transferir / gerenciar arquivos —
ftp_put(),ftp_get(),ftp_nlist(), etc. - Fechar —
ftp_close().
Conectando a um Servidor FTP
Estabeleça uma conexão com ftp_connect(). Ela recebe o nome do host (e porta e timeout opcionais) e retorna um objeto FTP\Connection em caso de sucesso (um resource antes do PHP 8.1), ou false em caso de falha.
<?php
$conn = ftp_connect("ftp.example.com", 21, 10); // host, port, timeout (seconds)
if ($conn === false) {
die("Could not connect to FTP server");
}
echo "Connected.";Note que conectar não faz login — neste ponto você tem um canal anônimo e não autenticado. Você ainda precisa chamar ftp_login() antes que o servidor permita fazer qualquer coisa útil.
Usando FTPS (FTP sobre TLS)
Para criptografar os canais de controle e dados, substitua ftp_connect() por ftp_ssl_connect(). O restante da API é idêntico:
<?php
$conn = ftp_ssl_connect("ftp.example.com");
if ($conn === false) {
die("Could not open a secure FTP connection");
}Fazendo Login e Modo Passivo
Após conectar, autentique-se com ftp_login(). Para servidores públicos que permitem acesso anônimo, use o nome de usuário anonymous com uma senha semelhante a um e-mail.
<?php
$conn = ftp_connect("ftp.example.com");
if (!ftp_login($conn, "username", "password")) {
ftp_close($conn);
die("Login failed");
}
// Most networks behind a firewall/NAT require passive mode.
ftp_pasv($conn, true);
echo "Logged in.";Por que o modo passivo importa. No modo ativo, o servidor abre uma conexão de dados de volta para o seu cliente, o que firewalls e roteadores NAT quase sempre bloqueiam. No modo passivo, o cliente abre a conexão de dados para o servidor, portanto funciona atrás de firewalls. Como regra geral, chame ftp_pasv($conn, true) logo após fazer login. Ele deve ser configurado após ftp_login(), não antes.
Enviando Arquivos (Upload)
Use ftp_put() para enviar um arquivo local para o servidor. Sua assinatura é ftp_put($conn, $remote_file, $local_file, $mode), onde $mode é FTP_BINARY ou FTP_ASCII.
<?php
$conn = ftp_connect("ftp.example.com");
ftp_login($conn, "username", "password");
ftp_pasv($conn, true);
if (ftp_put($conn, "/public_html/report.pdf", "report.pdf", FTP_BINARY)) {
echo "Upload successful";
} else {
echo "Upload failed";
}
ftp_close($conn);FTP_BINARY vs FTP_ASCII. Use FTP_BINARY para tudo que não seja texto simples — imagens, PDFs, arquivos compactados, executáveis — porque o modo ASCII reescreve as terminações de linha e corromperia dados binários. Use FTP_ASCII somente quando você quiser especificamente que as terminações de linha sejam traduzidas entre plataformas para arquivos de texto. Na dúvida, escolha FTP_BINARY; é o padrão seguro.
Para arquivos grandes, você pode fazer upload de forma não bloqueante com ftp_nb_put(), o que permite que seu script realize outras tarefas entre os chunks.
Baixando Arquivos (Download)
ftp_get() recupera um arquivo remoto para o sistema de arquivos local. A ordem dos argumentos é ftp_get($conn, $local_file, $remote_file, $mode) — note que o destino local vem primeiro, o oposto de ftp_put(). Confundir esses parâmetros é o erro de FTP mais comum.
<?php
$conn = ftp_connect("ftp.example.com");
ftp_login($conn, "username", "password");
ftp_pasv($conn, true);
// local_file first, then remote_file
if (ftp_get($conn, "backup.zip", "/backups/backup.zip", FTP_BINARY)) {
echo "Download successful";
} else {
echo "Download failed";
}
ftp_close($conn);Listando e Gerenciando Arquivos Remotos
A extensão FTP faz muito mais do que transferir arquivos. As funções de gerenciamento mais comuns incluem:
| Função | Finalidade |
|---|---|
ftp_nlist($conn, $dir) | Array com os nomes dos arquivos em um diretório |
ftp_rawlist($conn, $dir) | Listagem detalhada no estilo ls -l |
ftp_size($conn, $file) | Tamanho do arquivo em bytes (-1 em caso de erro) |
ftp_mkdir($conn, $dir) | Criar um diretório |
ftp_rmdir($conn, $dir) | Remover um diretório (vazio) |
ftp_delete($conn, $file) | Deletar um arquivo |
ftp_rename($conn, $from, $to) | Renomear / mover um arquivo |
ftp_chdir($conn, $dir) | Alterar o diretório de trabalho |
ftp_pwd($conn) | Diretório de trabalho atual |
ftp_chmod($conn, 0644, $file) | Alterar as permissões de um arquivo |
<?php
$conn = ftp_connect("ftp.example.com");
ftp_login($conn, "username", "password");
ftp_pasv($conn, true);
$files = ftp_nlist($conn, "/public_html");
foreach ($files as $file) {
echo $file, " — ", ftp_size($conn, $file), " bytes\n";
}
ftp_close($conn);Fechando a Conexão
Sempre libere a conexão com ftp_close() quando terminar. Envolver o fluxo de trabalho em try/finally garante que o socket seja fechado mesmo que um erro seja lançado no meio do caminho:
<?php
$conn = ftp_connect("ftp.example.com");
if (!$conn || !ftp_login($conn, "username", "password")) {
die("Connection or login failed");
}
try {
ftp_pasv($conn, true);
ftp_put($conn, "/public_html/index.html", "index.html", FTP_BINARY);
} finally {
ftp_close($conn);
}Boas Práticas e Armadilhas
- Prefira FTPS ou SFTP. Nunca envie credenciais por FTP simples pela internet pública.
- Sempre habilite o modo passivo (
ftp_pasv), a menos que tenha um motivo específico para não fazê-lo. - Escolha o modo de transferência correto —
FTP_BINARYpara dados binários,FTP_ASCIIapenas para texto onde a tradução de terminações de linha é desejada. - Atenção à ordem dos argumentos —
ftp_puté(remote, local),ftp_geté(local, remote). - Sempre feche a conexão com
ftp_close(). - Verifique todos os valores de retorno. As funções FTP retornam
falseem caso de falha em vez de lançar exceções, portanto falhas silenciosas são fáceis de ignorar. ext-ftpdeve estar habilitado. Confirme comextension_loaded('ftp'); se retornarfalse, habilite a extensão no seuphp.ini.
Tópicos Relacionados
- Manipulação de Arquivos PHP — leitura e escrita de arquivos locais.
- Upload de Arquivos PHP — tratamento de uploads de formulários HTTP.
- Sistema de Arquivos PHP — o conjunto mais amplo de funções do sistema de arquivos.
- Exceções PHP — tratamento estruturado de erros para
try/finally.