W3docs

readfile()

En PHP, la función readfile() lee el contenido de un archivo y lo envía al navegador. Es la forma más eficiente de servir archivos al cliente.

Introducción

La función readfile() de PHP lee un archivo y lo escribe directamente en el búfer de salida, devolviendo luego el número de bytes leídos. Como transmite el archivo directamente a la salida en lugar de cargarlo en una variable PHP, es la forma más eficiente en términos de memoria para enviar un archivo al navegador — razón por la que es la herramienta estándar para las descargas de archivos.

Este capítulo cubre la sintaxis y los parámetros de readfile(), qué devuelve, en qué se diferencia de funciones relacionadas como file_get_contents() y fread(), y cómo usarla de forma segura para mostrar y descargar archivos.

Sintaxis

readfile(
    string $filename,
    bool $use_include_path = false,
    ?resource $context = null
): int|false
ParámetroDescripción
$filenameRuta (o URL, si allow_url_fopen está activado) del archivo que se va a leer y enviar.
$use_include_pathSi es true, PHP también busca el archivo en el include_path. Por defecto es false.
$contextUn recurso de contexto de flujo opcional (creado con stream_context_create()).

Valor de retorno: el número de bytes leídos, o false en caso de error. Comprueba siempre el valor de retorno en lugar de ignorarlo, porque un archivo inexistente emite una advertencia y aun así envía una respuesta parcial (a menudo vacía).

Cómo funciona readfile()

Cuando se llama a readfile(), PHP abre el archivo, copia sus bytes al búfer de salida en fragmentos y los envía al cliente. El contenido completo nunca se carga en una cadena PHP, por lo que el uso de memoria se mantiene bajo incluso para archivos de varios gigabytes. La contrapartida: no hay posibilidad de transformar los datos — lo que se emite es una copia byte a byte del archivo.

readfile() frente a las alternativas

Elegir la función adecuada es importante:

  • readfile() — transmite un archivo directamente a la salida. Ideal para descargas y servir archivos sin procesar. No devuelve string, solo el número de bytes enviados.
  • file_get_contents() — lee el archivo completo en una cadena para que puedas modificarlo, buscarlo o almacenarlo. Usa memoria proporcional al tamaño del archivo.
  • fopen() + fread() — abre un manejador para una lectura detallada basada en posición; úsalo cuando necesites leer en fragmentos controlados o hacer seek.
  • highlight_file() — muestra un archivo con resaltado de sintaxis PHP (para mostrar código fuente).

Regla general: si solo necesitas enviar el archivo, usa readfile(); si necesitas procesar el archivo, léelo en una variable en su lugar.

Ejemplos

Ejemplo 1: Mostrar un archivo de texto

<?php

readfile('example.txt');

Esto envía el contenido de example.txt directamente al navegador. Sin una cabecera Content-Type definida, se aplica el valor predeterminado del servidor (normalmente text/html).

Ejemplo 2: Comprobar el valor de retorno

readfile() devuelve el número de bytes, lo que resulta útil para registros o manejo de errores:

<?php

$bytes = readfile('example.txt');

if ($bytes === false) {
    http_response_code(404);
    echo 'File not found.';
}

Ejemplo 3: Forzar una descarga

Para hacer que el navegador descargue un archivo en lugar de renderizarlo, envía las cabeceras correctas antes de cualquier salida y luego llama a 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-stream indica al navegador que se trata de una descarga binaria.
  • Content-Disposition: attachment; filename="..." activa el diálogo "Guardar como" y establece el nombre sugerido.
  • Content-Length permite al navegador mostrar una barra de progreso precisa.

Las cabeceras provienen de la función header() y deben enviarse antes de que la función emita cualquier byte — de lo contrario se obtiene el error "headers already sent".

Errores comunes

  • Nunca pases datos de usuario sin validar como $filename. Un valor como ../../etc/passwd permitiría a un atacante leer archivos arbitrarios (un ataque de traversal de rutas). Crea una lista blanca de archivos permitidos o procesa la ruta con basename() y confínala a un directorio conocido.
  • Sin salida antes de las cabeceras. Incluso un espacio o BOM antes de <?php cuenta como salida y rompe Content-Disposition.
  • Limpia el búfer de salida para archivos grandes. Si el búfer de salida está activado, el archivo puede seguir almacenándose en memoria. Llama a ob_end_clean() (o flush()) antes de readfile() al transmitir archivos muy grandes.
  • Leer URLs remotas requiere que allow_url_fopen esté habilitado en php.ini.

Conclusión

readfile() es la función de referencia en PHP para enviar un archivo al cliente con un uso mínimo de memoria: transmite bytes directamente a la salida y devuelve el número de bytes enviados. Úsala para descargas y servir archivos sin procesar, combínala con header() para las descargas, valida el nombre del archivo para evitar ataques de traversal de rutas, y recurre a file_get_contents() cuando necesites el contenido del archivo en una variable.

Práctica

Práctica
¿Qué hace la función readfile() de PHP?
¿Qué hace la función readfile() de PHP?
Was this page helpful?