readfile()
Em PHP, a função readfile() lê o conteúdo de um arquivo e o envia para o navegador. É uma forma conveniente de exibir o conteúdo de um arquivo.
Introdução
A função PHP readfile() lê um arquivo e o escreve diretamente no buffer de saída, retornando em seguida o número de bytes lidos. Como ela transmite o arquivo diretamente para a saída em vez de armazená-lo em uma variável PHP, é a forma mais eficiente em termos de memória para enviar um arquivo ao navegador — exatamente por isso é a ferramenta padrão para downloads de arquivos.
Este capítulo aborda a sintaxe e os parâmetros de readfile(), o que ela retorna, como difere de funções relacionadas como file_get_contents() e fread(), e como usá-la com segurança para exibir e baixar arquivos.
Sintaxe
readfile(
string $filename,
bool $use_include_path = false,
?resource $context = null
): int|false| Parâmetro | Descrição |
|---|---|
$filename | Caminho (ou URL, se allow_url_fopen estiver ativado) do arquivo a ser lido e enviado. |
$use_include_path | Se true, o PHP também pesquisa o include_path pelo arquivo. O padrão é false. |
$context | Um recurso de contexto de stream opcional (criado com stream_context_create()). |
Valor de retorno: o número de bytes lidos, ou false em caso de falha. Sempre verifique o valor de retorno em vez de ignorá-lo, pois um arquivo inexistente emite um aviso e ainda envia uma resposta parcial (geralmente vazia).
Como readfile() funciona
Ao chamar readfile(), o PHP abre o arquivo, copia seus bytes para o buffer de saída em partes e os envia ao cliente. O conteúdo completo nunca é carregado em uma string PHP, portanto o uso de memória permanece baixo mesmo para arquivos de vários gigabytes. A contrapartida: você não tem chance de transformar os dados — o que sai é uma cópia byte a byte do arquivo.
readfile() vs. as alternativas
Escolher a função certa é importante:
readfile()— transmite um arquivo diretamente para a saída. Ideal para downloads e servir arquivos brutos. Não retorna string, apenas a contagem de bytes enviados.file_get_contents()— lê o arquivo inteiro em uma string para que você possa modificá-lo, pesquisá-lo ou armazená-lo. Usa memória proporcional ao tamanho do arquivo.fopen()+fread()— abre um handle para leitura refinada e baseada em posição; use quando precisar ler em partes controladas ou navegar pelo arquivo.highlight_file()— exibe um arquivo com realce de sintaxe PHP (para mostrar código-fonte).
Regra geral: se você só precisa enviar o arquivo, use readfile(); se precisa processar o arquivo, leia-o em uma variável.
Exemplos
Exemplo 1: Exibindo um arquivo de texto
<?php
readfile('example.txt');Isso envia o conteúdo de example.txt diretamente ao navegador. Sem um cabeçalho Content-Type definido, o padrão do servidor é aplicado (geralmente text/html).
Exemplo 2: Verificando o valor de retorno
readfile() retorna a contagem de bytes, o que é útil para logging ou tratamento de erros:
<?php
$bytes = readfile('example.txt');
if ($bytes === false) {
http_response_code(404);
echo 'File not found.';
}Exemplo 3: Forçando um download
Para fazer o navegador baixar um arquivo em vez de renderizá-lo, envie os cabeçalhos corretos antes de qualquer saída e, em seguida, chame readfile():
<?php
$file = 'report.pdf';
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;Content-Type: application/octet-streaminforma ao navegador que se trata de um download binário.Content-Disposition: attachment; filename="..."aciona o diálogo "Salvar como" e define o nome sugerido.Content-Lengthpermite que o navegador exiba uma barra de progresso precisa.
Os cabeçalhos vêm da função header() e devem ser enviados antes que a função gere qualquer byte — caso contrário, você receberá um erro "headers already sent".
Problemas comuns
- Nunca passe entradas não sanitizadas do usuário como
$filename. Um valor como../../etc/passwdpermitiria que um invasor lesse arquivos arbitrários (um ataque de path traversal). Crie uma lista de permissões de arquivos permitidos ou processe o caminho combasename()e restrinja-o a um diretório conhecido. - Sem saída antes dos cabeçalhos. Até mesmo um espaço perdido ou BOM antes de
<?phpconta como saída e quebra oContent-Disposition. - Limpe o buffer de saída para arquivos grandes. Se o buffer de saída estiver ativado, o arquivo ainda pode ser armazenado em buffer na memória. Chame
ob_end_clean()(ouflush()) antes dereadfile()ao transmitir arquivos muito grandes. - Leitura de URLs remotas requer que
allow_url_fopenesteja habilitado nophp.ini.
Conclusão
readfile() é a função padrão do PHP para enviar um arquivo ao cliente com o mínimo de uso de memória: ela transmite bytes diretamente para a saída e retorna o número de bytes enviados. Use-a para downloads e para servir arquivos brutos, combine-a com header() para downloads, valide o nome do arquivo para evitar ataques de path traversal e prefira file_get_contents() quando precisar do conteúdo do arquivo em uma variável.