W3docs

readfile()

En PHP, la fonction readfile() lit le contenu d'un fichier et l'envoie directement au navigateur. C'est le moyen idéal pour les téléchargements.

Introduction

La fonction PHP readfile() lit un fichier et l'écrit directement dans le tampon de sortie, puis retourne le nombre d'octets lus. Comme elle transmet le fichier directement en sortie au lieu de le stocker dans une variable PHP, c'est la méthode la plus économe en mémoire pour envoyer un fichier au navigateur — c'est pourquoi elle est l'outil standard pour les téléchargements de fichiers.

Ce chapitre couvre la syntaxe et les paramètres de readfile(), ce qu'elle retourne, en quoi elle diffère des fonctions similaires comme file_get_contents() et fread(), et comment l'utiliser en toute sécurité pour afficher et télécharger des fichiers.

Syntaxe

readfile(
    string $filename,
    bool $use_include_path = false,
    ?resource $context = null
): int|false
ParamètreDescription
$filenameChemin (ou URL, si allow_url_fopen est activé) du fichier à lire et à afficher en sortie.
$use_include_pathSi true, PHP recherche également le fichier dans l'include_path. Par défaut à false.
$contextUne ressource de contexte de flux optionnelle (créée avec stream_context_create()).

Valeur de retour : le nombre d'octets lus, ou false en cas d'échec. Vérifiez toujours la valeur de retour plutôt que de l'ignorer, car un fichier manquant émet un avertissement et envoie quand même une réponse partielle (souvent vide).

Fonctionnement de readfile()

Lorsque vous appelez readfile(), PHP ouvre le fichier, copie ses octets dans le tampon de sortie par blocs, puis les envoie au client. Le contenu complet n'est jamais chargé dans une chaîne PHP, ce qui maintient une faible utilisation de la mémoire même pour des fichiers de plusieurs gigaoctets. La contrepartie : vous n'avez aucune possibilité de transformer les données — ce qui sort est une copie octet par octet du fichier.

readfile() vs. les alternatives

Choisir la bonne fonction est important :

  • readfile() — transmet un fichier directement en sortie. Idéal pour les téléchargements et la diffusion de fichiers bruts. Pas de chaîne de retour, juste le nombre d'octets envoyés.
  • file_get_contents() — lit l'intégralité du fichier dans une chaîne afin de pouvoir la modifier, la rechercher ou la stocker. Utilise une mémoire proportionnelle à la taille du fichier.
  • fopen() + fread() — ouvre un descripteur pour une lecture précise basée sur la position ; à utiliser lorsque vous avez besoin de lire par blocs contrôlés ou de vous déplacer dans le fichier.
  • highlight_file() — affiche un fichier avec la coloration syntaxique PHP (pour montrer le code source).

Règle générale : si vous avez seulement besoin d'envoyer le fichier, utilisez readfile() ; si vous avez besoin de traiter le fichier, lisez-le dans une variable à la place.

Exemples

Exemple 1 : Afficher un fichier texte

<?php

readfile('example.txt');

Cela envoie le contenu de example.txt directement au navigateur. Sans en-tête Content-Type défini, la valeur par défaut du serveur s'applique (généralement text/html).

Exemple 2 : Vérifier la valeur de retour

readfile() retourne le nombre d'octets, ce qui est pratique pour la journalisation ou la gestion des erreurs :

<?php

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

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

Exemple 3 : Forcer un téléchargement

Pour que le navigateur télécharge un fichier au lieu de l'afficher, envoyez les bons en-têtes avant toute sortie, puis appelez 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 indique au navigateur qu'il s'agit d'un téléchargement binaire.
  • Content-Disposition: attachment; filename="..." déclenche la boîte de dialogue "Enregistrer sous" et définit le nom suggéré.
  • Content-Length permet au navigateur d'afficher une barre de progression précise.

Les en-têtes proviennent de la fonction header() et doivent être envoyés avant que la fonction n'envoie des octets — sinon vous obtenez une erreur "headers already sent".

Pièges courants

  • Ne transmettez jamais une entrée utilisateur non assainie comme $filename. Une valeur comme ../../etc/passwd permettrait à un attaquant de lire des fichiers arbitraires (une attaque par traversée de répertoire). Autorisez uniquement les fichiers prévus ou faites passer le chemin par basename() et limitez-le à un répertoire connu.
  • Pas de sortie avant les en-têtes. Même un espace ou un BOM avant <?php compte comme une sortie et casse Content-Disposition.
  • Videz le tampon de sortie pour les grands fichiers. Si la mise en tampon de sortie est activée, le fichier peut toujours être mis en mémoire tampon. Appelez ob_end_clean() (ou flush()) avant readfile() lors de la diffusion de très grands fichiers.
  • La lecture d'URL distantes nécessite que allow_url_fopen soit activé dans php.ini.

Conclusion

readfile() est la fonction PHP de référence pour envoyer un fichier au client avec une utilisation minimale de la mémoire : elle transmet les octets directement en sortie et retourne le nombre d'octets envoyés. Utilisez-la pour les téléchargements et la diffusion de fichiers bruts, associez-la à header() pour les téléchargements, validez le nom de fichier pour éviter les attaques par traversée de répertoire, et optez pour file_get_contents() lorsque vous avez réellement besoin du contenu du fichier dans une variable.

Pratique

Pratique
Que fait la fonction PHP readfile() ?
Que fait la fonction PHP readfile() ?
Was this page helpful?