W3docs

ftp_fget()

A função ftp_fget() do PHP baixa um arquivo remoto do servidor FTP e o salva em um identificador de arquivo local aberto.

O que é ftp_fget()?

ftp_fget() faz o download de um arquivo de um servidor FTP e o grava em um identificador de arquivo local já aberto. Essa é a principal diferença em relação a ftp_get(): ftp_get() recebe um caminho local e cria o arquivo para você, enquanto ftp_fget() recebe um recurso de arquivo aberto (o valor retornado por fopen()). Como você controla o identificador, ftp_fget() é útil quando você quer gravar em um stream que não é um arquivo comum — um stream temporário (php://temp), um buffer em memória ou um identificador que você posicionou com fseek().

Esta página aborda a assinatura da função, um download completo e funcional, como escolher um modo de transferência, como retomar um download interrompido e o tratamento de erros necessário em código real.

A extensão FTP procedural ainda faz parte do PHP. A partir do PHP 8.1, a conexão é um objeto FTP\Connection em vez de um resource, mas o código que você escreve permanece o mesmo. Para transferências criptografadas, use ftp_ssl_connect() no lugar de ftp_connect().

Sintaxe de ftp_fget()

ftp_fget(
    FTP\Connection $ftp,
    resource $stream,
    string $remote_filename,
    int $mode = FTP_BINARY,
    int $offset = 0
): bool
ParâmetroDescrição
$ftpA conexão retornada por ftp_connect() (e autenticada com ftp_login()).
$streamUm ponteiro de arquivo local aberto no qual os dados baixados serão gravados. Deve ser aberto para escrita ('w', 'w+', 'a', etc.).
$remote_filenameCaminho para o arquivo no servidor FTP.
$modeModo de transferência: FTP_BINARY (o padrão desde o PHP 7.3) para qualquer arquivo não textual, ou FTP_ASCII para texto simples cujas terminações de linha devem ser normalizadas.
$offsetPosição em bytes no stream local a partir da qual começar a gravar — usado para retomar um download parcial. O padrão é 0.

Retorna true em caso de sucesso e false em caso de falha.

Fazendo download de um arquivo com ftp_fget()

Um download completo tem quatro etapas: conectar, fazer login, abrir um identificador local e depois buscar. Sempre feche tanto o identificador quanto a conexão quando terminar.

<?php

// 1. Connect (returns false on failure)
$ftp = ftp_connect('ftp.example.com');
if ($ftp === false) {
    exit("Could not connect to the FTP server.\n");
}

// 2. Authenticate
if (!ftp_login($ftp, 'username', 'password')) {
    exit("FTP login failed.\n");
}

// Most networks need passive mode so the data channel works behind NAT/firewalls
ftp_pasv($ftp, true);

// 3. Open a local handle for writing
$handle = fopen('downloads/report.pdf', 'w');

// 4. Download into that handle (binary mode for a PDF)
if (ftp_fget($ftp, $handle, 'public/report.pdf', FTP_BINARY)) {
    echo "Download complete.\n";
} else {
    echo "Download failed.\n";
}

fclose($handle);
ftp_close($ftp);

Chamar ftp_pasv() para habilitar o modo passivo é quase sempre necessário quando o cliente está atrás de um firewall ou NAT, que é o caso mais comum; sem isso, a transferência de dados pode travar.

Escolhendo um modo de transferência

  • FTP_BINARY copia o arquivo byte a byte. Use-o para imagens, arquivos compactados, PDFs, executáveis — qualquer coisa que não seja texto simples. É o padrão seguro.
  • FTP_ASCII converte as terminações de linha para corresponder à plataforma de destino. Use-o apenas para arquivos de texto e somente quando você realmente deseja essa conversão. Enviar um arquivo binário no modo ASCII o corrompe.

Retomando um download interrompido

O parâmetro $offset permite continuar um download que foi interrompido. Abra o arquivo parcial existente para acrescentar dados, descubra quantos bytes você já tem e informe a ftp_fget() para começar a gravar a partir daí:

<?php

$local = 'downloads/big.iso';

// Open in append mode so previously downloaded bytes are preserved
$handle = fopen($local, 'a');

// How many bytes we already have locally
$alreadyHave = file_exists($local) ? filesize($local) : 0;

if (ftp_fget($ftp, $handle, 'images/big.iso', FTP_BINARY, $alreadyHave)) {
    echo "Resumed and finished the download.\n";
}

fclose($handle);

Para arquivos muito grandes, você pode preferir a variante não bloqueante ftp_nb_fget(), que devolve o controle ao seu script entre os blocos para que você possa exibir o progresso.

Tratamento de erros

ftp_fget() retorna apenas false — não lança exceções — portanto verifique o valor de retorno de cada etapa, não apenas o do download. Comparar com === evita tratar um valor falso, mas válido, de forma incorreta.

<?php

$handle = fopen('downloads/data.csv', 'w');
if ($handle === false) {
    exit("Could not open the local file for writing.\n");
}

if (ftp_fget($ftp, $handle, 'exports/data.csv', FTP_ASCII) === false) {
    // Common causes: wrong remote path, no read permission, or a dropped data channel
    echo "Failed to retrieve the file.\n";
} else {
    echo "File retrieved successfully.\n";
}

fclose($handle);

Armadilhas comuns

  • Passar um caminho em vez de um identificador. O segundo argumento deve ser um recurso proveniente de fopen(). Se você tiver um caminho, use ftp_get().
  • Esquecer o modo passivo. Atrás de um firewall, pular ftp_pasv() pode fazer a transferência travar silenciosamente.
  • Modo de transferência errado. O modo ASCII danifica arquivos binários; o modo binário deixa terminações de linha inconsistentes em arquivos de texto apenas em plataformas raras, portanto o binário é o padrão mais seguro.
  • Não fechar os recursos. Chame fclose() e ftp_close() para que os buffers sejam liberados e a conexão seja encerrada.

Funções relacionadas

  • ftp_get() — faz download para um caminho local (sem necessidade de identificador).
  • ftp_fput() — o equivalente de upload, enviando a partir de um identificador aberto.
  • ftp_nb_fget() — download não bloqueante em um identificador.
  • ftp_connect() e ftp_login() — abrem e autenticam a sessão.

Prática

Prática
Qual é a funcionalidade da função ftp_fget() em PHP?
Qual é a funcionalidade da função ftp_fget() em PHP?
Was this page helpful?