fpassthru()
A função fpassthru() do PHP lê os dados restantes de um ponteiro de arquivo e os envia diretamente para a saída, ideal para arquivos grandes.
O que é a Função fpassthru()?
A função fpassthru() é uma função PHP nativa que lê todos os dados restantes de um ponteiro de arquivo aberto — a partir da posição atual do ponteiro até o final do arquivo (EOF) — e os grava diretamente no fluxo de saída (o que o navegador ou o terminal recebe). Como ela transmite os dados em partes em vez de carregar o arquivo inteiro em uma string, é bem adequada para enviar arquivos grandes sem esgotar o limite de memória do PHP.
Esta página aborda a sintaxe da função, um padrão de uso passo a passo, um exemplo real de download de arquivo, como ela difere de readfile(), e os pontos de atenção que vale conhecer.
Ela retorna o número de bytes gravados na saída em caso de sucesso, ou false em caso de falha.
Veja a sintaxe básica da função fpassthru():
A sintaxe PHP de fpassthru()
fpassthru(resource $stream): int|falseOnde $stream é um ponteiro de arquivo que deve ser válido e já estar aberto (tipicamente o valor de retorno de fopen()). Após o retorno de fpassthru(), o ponteiro está no EOF e os dados foram consumidos — não é possível lê-los novamente sem rebobinar.
Como Usar a Função fpassthru()?
Usar a função fpassthru() é simples. Veja os passos a seguir:
- Abra o arquivo com
fopen()e certifique-se de que o ponteiro está na posição inicial desejada. - Chame
fpassthru()com o ponteiro do arquivo. Ela lerá até o EOF e gravará no fluxo de saída. - Verifique o valor de retorno para confirmar o sucesso e, em seguida, feche o arquivo com
fclose().
Veja um trecho de código de exemplo que demonstra como usar a função fpassthru():
Como Usar a Função fpassthru()?
<?php
$filename = 'largefile.txt';
$file = fopen($filename, 'r');
if ($file) {
if (fpassthru($file) === false) {
echo "Error reading file!";
}
fclose($file);
} else {
echo "Unable to open file!";
}Neste exemplo, abrimos o arquivo largefile.txt usando a função fopen() no modo somente leitura. Verificamos se o arquivo foi aberto com sucesso usando uma instrução if e, se foi, enviamos seu conteúdo para o fluxo de saída padrão com fpassthru(). Verificamos o valor de retorno para tratar possíveis erros de leitura e, em seguida, fechamos o identificador com fclose().
Nota sobre buffer de saída: Se o buffer de saída do PHP estiver ativo (por exemplo, via
ob_start()),fpassthru()gravará diretamente no buffer de saída atual em vez de enviar os dados imediatamente ao navegador.
Leitura a Partir da Posição Atual, Não do Arquivo Inteiro
Um detalhe importante é que fpassthru() começa na posição atual do ponteiro. Se você já leu parte do arquivo (por exemplo com fgets() ou fread()), apenas os bytes restantes são enviados. Isso permite ler um cabeçalho manualmente e transmitir o restante:
<?php
$file = fopen('php://temp', 'r+');
fwrite($file, "HEADER\nbody-line-1\nbody-line-2\n");
rewind($file);
// Consume the first line manually.
echo "First line: " . fgets($file);
// Stream everything left after the pointer.
fpassthru($file);
fclose($file);Isso imprime:
First line: HEADER
body-line-1
body-line-2A linha HEADER não é repetida, porque o ponteiro já havia avançado além dela quando fpassthru() foi executada.
Enviando um Arquivo como Download
O uso mais comum em produção de fpassthru() é transmitir um arquivo para o navegador como download. Defina os cabeçalhos adequados, abra o arquivo no modo binário ('rb') e deixe fpassthru() enviar os bytes:
<?php
$path = '/var/www/files/report.pdf';
if (is_readable($path)) {
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="report.pdf"');
header('Content-Length: ' . filesize($path));
$file = fopen($path, 'rb');
fpassthru($file);
fclose($file);
exit;
}
http_response_code(404);
echo 'File not found.';O modo 'rb' é importante no Windows, onde o modo de texto padrão corromperia dados binários como imagens, PDFs ou arquivos compactados. No Linux e no macOS o sinalizador b é inofensivo, por isso é uma boa prática sempre incluí-lo em downloads.
fpassthru() vs. readfile()
Ambas as funções transmitem um arquivo para a saída, mas operam em níveis diferentes:
fpassthru($stream) | readfile($path) | |
|---|---|---|
| Entrada | Um ponteiro de arquivo já aberto | Um caminho de arquivo (abre internamente) |
| Ponto de início | A posição atual do ponteiro | Sempre o início do arquivo |
| Melhor quando | Você precisa ler parte do arquivo primeiro, ou já tem um identificador aberto | Você quer simplesmente exibir um arquivo inteiro com uma única chamada |
Se você simplesmente quer exibir um arquivo inteiro e não tem um identificador aberto, readfile() é mais conciso. Use fpassthru() quando já tiver um ponteiro de arquivo ou precisar pular parte do fluxo antes de transmitir.
Conclusão
A função fpassthru() é uma ferramenta útil em PHP para ler arquivos grandes sem carregá-los na memória. Seguindo os passos descritos neste guia, você pode facilmente usar a função fpassthru() nos seus projetos PHP para ler o conteúdo de arquivos a partir da posição atual do ponteiro e enviá-los para o fluxo de saída padrão.