Menu

PHP fopen() : ouvrir, lire et écrire des fichiers (modes)

fopen('data.txt', 'r') ouvre un fichier et renvoie une poignée, ou false en cas d'échec. Lisez depuis la poignée avec fgets() ou fread(), écrivez avec fwrite(), fermez-la avec fclose(). Le mode ('r', 'w', 'a', 'x', 'c' et leurs formes +) décide de ce que vous pouvez faire.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

fopen('data.txt', 'r') ouvre un fichier et renvoie une poignée, une ressource de flux que les autres fonctions de fichier prennent en premier argument. Lisez avec fgets() (une ligne) ou fread() (un nombre d'octets), écrivez avec fwrite(), et fermez avec fclose(). Le second argument est le mode : 'r' pour lire, 'w' pour écrire, 'a' pour ajouter à la fin.

Sortie :

Got: apple
Got: banana
Got: cherry

fopen() renvoie false quand elle ne peut pas ouvrir le fichier (il n'existe pas en mode r, un dossier manque, pas de permission), et PHP affiche un warning comme :

Warning: fopen(missing.txt): Failed to open stream: No such file or directory in /home/index.php on line 2

Vérifiez donc false avant d'utiliser la poignée. Pour lire ou écrire un petit fichier entier en un appel, file_get_contents() et file_put_contents() sont plus courtes ; fopen() sert aux fichiers que vous lisez morceau par morceau ou gardez ouverts.

Les modes de fopen

ModeLectureÉcritureSi le fichier existeS'il n'existe pasCommence à
rouinonl'ouvreéchouedébut
r+ouiouil'ouvre, garde le contenuéchouedébut
wnonouile videle créedébut
w+ouiouile videle créedébut
anonouigarde le contenule créefin, chaque écriture s'ajoute
a+ouiouigarde le contenule créefin, chaque écriture s'ajoute
xnonouiéchouele créedébut
x+ouiouiéchouele créedébut
cnonouigarde le contenule créedébut
c+ouiouigarde le contenule créedébut

Deux lignes surprennent. r+ écrit par-dessus les octets existants, sans insérer, et a+ écrit toujours à la fin, même après avoir déplacé le pointeur avec fseek() (le déplacer n'affecte que les lectures) :

Sortie :

Xbc
Xbc
Xbc
end

Sous Windows, vous verrez peut-être 'rb' ou 'wb' : l'option b signifie binaire et empêche Windows de convertir les fins de ligne. Elle ne fait rien sous Linux et macOS, l'ajouter est donc sans risque et portable.

Lire un fichier ligne par ligne avec fgets()

fgets() renvoie la ligne suivante, \n compris, et false à la fin du fichier. Comme une seule ligne est en mémoire à la fois, cette boucle gère un fichier de journal de n'importe quelle taille, et vous pouvez vous arrêter tôt avec break :

Sortie :

2 errors in 5 lines
line 2: database timeout
line 4: disk full

Comparez à false avec !==, pas avec un simple while ($line = fgets($fh)) : une ligne contenant seulement "0" sans saut de ligne (la dernière ligne d'un fichier peut l'être) est évaluée à faux et terminerait la boucle trop tôt.

Écrire et ajouter avec fwrite()

fwrite() écrit une chaîne à la position courante et renvoie le nombre d'octets écrits, ou false en cas d'échec. fputs() est la même fonction sous un autre nom. Ouvrez avec 'a' pour ajouter à la fin d'un fichier sans toucher à son contenu :

Sortie :

wrote 12 bytes
wrote 13 bytes
wrote 15 bytes
visit /home
visit /about
visit /contact
visit /home

PHP_EOL est la fin de ligne du système sur lequel tourne PHP (\n sous Linux et macOS, \r\n sous Windows). Pour des fichiers lus par d'autres programmes, choisissez-en une explicitement, en général "\n".

Lire et écrire des fichiers CSV avec fgetcsv() et fputcsv()

fputcsv() écrit un tableau comme une ligne CSV et met entre guillemets les champs qui contiennent des virgules, des guillemets ou des sauts de ligne. fgetcsv() relit une ligne sous forme de tableau. Passez explicitement le séparateur, le caractère d'encadrement et un caractère d'échappement vide : cela donne du CSV standard, et PHP 8.4 affiche un avis de dépréciation quand l'argument d'échappement est omis.

Sortie :

name,city,note
Ada,London,"likes ""math"", a lot"
Linus,Helsinki,kernel

Ada lives in London: likes "math", a lot
Linus lives in Helsinki: kernel

Découper les lignes avec explode(',', $line) casse dès qu'un champ contient une virgule ; fgetcsv() gère les guillemets pour vous. Pour un fichier séparé par des points-virgules (courant dans les exports Excel en Europe), passez ';' comme séparateur.

Se déplacer dans un fichier avec fseek(), ftell() et rewind()

Un fichier ouvert a une position. Les lectures et écritures commencent là et l'avancent. ftell() indique où elle se trouve, fseek() la déplace à une position en octets, et rewind() revient au début. Avec w+, vous pouvez écrire un fichier et le relire par la même poignée :

Sortie :

11
world
hello world

Verrouiller un fichier avec flock()

Deux requêtes qui lisent un compteur, ajoutent un et le réécrivent en même temps peuvent toutes deux lire 41 et toutes deux écrire 42. flock() avec LOCK_EX fait attendre la seconde jusqu'à ce que la première libère le verrou. Le mode c+ est le bon ici : il crée le fichier si nécessaire et, contrairement à w+, ne le vide pas avant que vous teniez le verrou.

Sortie :

Visitor number 1
Visitor number 2
Visitor number 3

Les verrous sont consultatifs : ils n'arrêtent que l'autre code qui appelle aussi flock(). Pour ajouter une ligne, file_put_contents($path, $line, FILE_APPEND | LOCK_EX) fait la même chose en un appel.

Erreur fréquente : while (!feof($fh))

Beaucoup d'anciens tutoriels bouclent avec feof(). Elle ne renvoie true qu'après qu'une lecture a déjà atteint la fin, donc la boucle tourne une fois de plus qu'il n'y a de lignes et le dernier fgets() renvoie false :

Sortie :

string(2) "a
"
string(2) "b
"
string(2) "c
"
bool(false)
4 rounds for 3 lines

Ce false en trop devient une ligne vide dans un rapport ou un élément vide dans un tableau. Bouclez sur la lecture elle-même, while (($line = fgets($fh)) !== false), comme le font tous les autres exemples de cette page.

Questions fréquentes

Quels sont les modes de fopen en PHP ?

r lit, w écrit après avoir vidé le fichier, a écrit à la fin, x crée un nouveau fichier et échoue s'il existe, et c écrit sans le vider. Ajouter + (r+, w+, a+, x+, c+) permet à la fois de lire et d'écrire. Tous les modes sauf r et r+ créent le fichier s'il manque.

Quelle est la différence entre w et a dans fopen ?

w vide le fichier dès l'ouverture et écrit depuis le début. a garde le contenu et chaque fwrite() va à la fin du fichier, même après fseek(), ce qui en fait le mode des fichiers de journal.

Comment lire un fichier CSV en PHP ?

Ouvrez-le avec fopen($path, 'r') et appelez fgetcsv() dans une boucle : while (($row = fgetcsv($fh, null, ',', '"', '')) !== false) { ... }. Chaque appel renvoie une ligne sous forme de tableau de champs, avec les guillemets et les virgules internes gérés pour vous.

Faut-il appeler fclose en PHP ?

PHP ferme tous les fichiers ouverts à la fin du script, donc un script court fonctionne sans. Appelez quand même fclose() dès que vous avez fini : cela vide les écritures en tampon, libère les verrous pris avec flock() et évite qu'un script de longue durée manque de poignées de fichier.

Illustration des langages de programmation de Coddy

Apprendre à coder avec Coddy

COMMENCER