Dans ce chapitre, nous allons voir comment lire et écrire des fichiers en PHP. Pour les cas simples, PHP propose deux fonctions très pratiques : file_put_contents() pour écrire dans un fichier et file_get_contents() pour lire son contenu.
On verra aussi les limites de ces fonctions lorsque les fichiers deviennent volumineux, puis une approche plus adaptée avec fopen(), fgets() et fwrite().
Écrire dans un fichier
Pour écrire dans un fichier, on utilise la fonction file_put_contents(). Elle attend au minimum deux paramètres :
- le chemin vers le fichier.
- les données à écrire.
Ces données peuvent être une chaîne de caractères, un tableau ou une ressource.
Si le fichier n'existe pas, PHP le crée automatiquement. En revanche, si le fichier existe déjà, son contenu est remplacé.
Attention aux chemins relatifs
Lorsque l'on indique simplement demo.txt, le chemin est relatif au contexte d'exécution de PHP. Par exemple, si on lance le script depuis la racine du projet, le fichier sera créé à cet endroit, même si le script se trouve dans un sous-dossier.
Pour éviter les surprises, on peut utiliser la constante __DIR__, qui contient le chemin du dossier du fichier courant.
On utilise ici DIRECTORY_SEPARATOR plutôt qu'un / ou un \, car le séparateur de dossier n'est pas le même suivant le système d'exploitation.
Si vous avez besoin de remonter dans les dossiers parents, vous pouvez utiliser dirname() :
Ce n'est pas forcément très pratique si l'on doit remonter beaucoup de niveaux, mais cela permet de construire un chemin à partir du fichier courant.
Ajouter du contenu à la fin du fichier
Par défaut, file_put_contents() écrase le contenu existant. Si on souhaite ajouter du texte à la suite, il faut utiliser le drapeau FILE_APPEND en troisième paramètre.
Dans ce cas, le nouveau contenu est ajouté à la fin du fichier.
Gérer les erreurs d'écriture
Une erreur peut arriver si PHP n'a pas les permissions nécessaires pour écrire dans le dossier ciblé. Cela dépend notamment de l'utilisateur qui exécute PHP.
file_put_contents() retourne le nombre d'octets écrits, ou false en cas d'erreur.
Le @ permet de rendre l'erreur silencieuse, mais si vous l'utilisez, il faut absolument gérer le cas d'erreur derrière.
Lire un fichier avec file_get_contents
Pour lire un fichier, on peut utiliser file_get_contents(). La fonction prend le chemin du fichier et retourne tout son contenu sous forme de chaîne de caractères.
Cette fonction est très simple à utiliser et convient très bien pour des petits fichiers. On peut parfois voir file_get_contents() utilisé avec une URL :
Même si cela peut fonctionner suivant la configuration de PHP, ce n'est pas conseillé. Pour récupérer une URL, il vaut mieux utiliser des outils dédiés, qui offrent plus de contrôle, notamment en cas d'erreur (on verra ce cas plus tard dans la formation).
Les limites avec les gros fichiers
file_get_contents() lit l'intégralité du fichier en mémoire. Si le fichier est très volumineux, cela peut provoquer une erreur du type :
Pour travailler plus finement sur un fichier, on peut utiliser fopen(). Cette fonction ouvre le fichier et retourne une ressource.
Le second paramètre correspond au mode d'ouverture. Le mode r permet d'ouvrir le fichier en lecture seule. Avec cette approche, PHP ne charge pas tout le fichier d'un coup. Il place un curseur au début du fichier, puis on peut lire progressivement son contenu.
Lire progressivement avec fread et fgets
La fonction fread() permet de lire un certain nombre d'octets depuis la position courante du curseur.
Attention cependant : fread() travaille en octets. Avec certains caractères UTF-8, un caractère peut être stocké sur plusieurs octets. Si on lit au milieu d'un caractère, l'affichage peut poser problème. Pour lire un fichier ligne par ligne, fgets() est plus adapté.
À chaque appel, fgets() lit la ligne courante puis avance le curseur à la ligne suivante. On peut donc parcourir un fichier avec une boucle :
Ici, l'assignation dans le while est volontaire : fgets() retourne une chaîne tant qu'une ligne est lue, puis false lorsqu'on arrive à la fin du fichier ou en cas d'erreur. Quand on a fini de travailler avec un fichier, il faut penser à le fermer avec fclose().
Écrire avec fwrite
Avec fopen(), on peut aussi ouvrir un fichier en lecture et écriture. Le mode r+ permet de lire et d'écrire en plaçant le curseur au début du fichier.
Il faut faire attention : fwrite() écrit à partir de la position courante du curseur. Il ne décale pas automatiquement le contenu existant, il écrit par-dessus. Pour ajouter du contenu à la fin d'un fichier, on utilisera plutôt un mode qui place le curseur à la fin, comme a.
Lire un CSV
Avec un CSV, les valeurs sont séparées par des virgules. Le problème, c'est que certaines colonnes peuvent elles-mêmes contenir des virgules. Dans ce cas, les valeurs sont entourées de guillemets.
Un simple explode(',') ne suffit donc pas toujours.
Pour parser correctement une ligne CSV, PHP propose str_getcsv() :
Cette fonction respecte la syntaxe CSV et permet de récupérer correctement les différentes colonnes.
Quelle méthode choisir ?
Le choix dépend de la situation :
file_put_contents()etfile_get_contents()sont pratiques pour des petits fichiers et des manipulations simples ;file()peut servir à récupérer toutes les lignes d'un fichier, mais charge aussi tout le fichier en mémoire ;fopen(),fgets(),fread()etfwrite()sont plus adaptés aux gros fichiers ou aux manipulations plus précises.
Pour aller plus loin, vous pouvez consulter la documentation officielle PHP sur file_get_contents(), file_put_contents() et fopen().
Avertissement : À partir de PHP 8.4.0, l'utilisation de la valeur par défaut de escape est dépréciée. Elle doit être fournie explicitement soit par position, soit par l'utilisation des arguments nommés. Dans le fichier menu.php à la ligne 6 :