Ouvrir, lire et fermer un fichier en PHP

Dans la leçon précédente, nous avons appris à lire un fichier texte entièrement. Souvent, cependant, nous ne voudrons lire et récupérer qu’une partie d’un fichier. Nous allons voir comment faire cela dans cette nouvelle leçon.

 

Ouvrir un fichier en PHP

Pour lire un fichier partie par partie, nous allons avant tout devoir l’ouvrir. Pour ouvrir un fichier en PHP, nous allons utiliser la fonction fopen(), abréviation de « file open » ou « ouverture de fichier » en français.

On va devoir passer le chemin relatif menant à notre fichier ainsi qu’un « mode » en arguments à cette fonction qui va alors retourner en cas de succès une ressource de pointeur de fichier, c’est-à-dire pour le dire très simplement une ressource qui va nous permettre de manipuler notre fichier.

Le mode choisi détermine le type d’accès au fichier et donc les opérations qu’on va pouvoir effectuer sur le fichier. On va pouvoir choisir parmi les modes suivants :

Mode d’ouvertureDescription
rOuvre un fichier en lecture seule. Il est impossible de modifier le fichier.
r+Ouvre un fichier en lecture et en écriture.
aOuvre un fichier en écriture seule en conservant les données existantes. Si le fichier n’existe pas, le PHP tente de le créer.
a+Ouvre un fichier en lecture et en écriture en conservant les données existantes. Si le fichier n’existe pas, le PHP tente de le créer.
wOuvre un fichier en écriture seule. Si le fichier existe, les informations existantes seront supprimées. S’il n’existe pas, crée un fichier.
w+Ouvre un fichier en lecture et en écriture. Si le fichier existe, les informations existantes seront supprimées. S’il n’existe pas, crée un fichier.
xCrée un nouveau fichier accessible en écriture seulement. Retourne false et une erreur si le fichier existe déjà.
x+Crée un nouveau fichier accessible en lecture et en écriture. Retourne false et une erreur si le fichier existe déjà.
cOuvre un fichier pour écriture seulement. Si le fichier n’existe pas, il sera crée. Si il existe, les informations seront conservées.
c+Ouvre un fichier pour lecture et écriture. Si le fichier n’existe pas, il sera crée. Si il existe, les informations seront conservées.
eLe mode e est particulier et n’est pas toujours disponible. Nous n’en parlerons pas ici.

Comme vous pouvez le constater, le choix du mode influe fortement sur les opérations que nous allons pouvoir réaliser sur le fichier en question.

Par exemple lorsqu’on ouvre un fichier en lecture seulement toute modification de ce fichier est impossible, ce qui n’est pas le cas si on choisit un mode permettant l’écriture dans ce fichier.

Notez par ailleurs qu’on ajoutera généralement la lettre b au paramètre « mode » de fopen(). Cela permet une meilleure compatibilité et évite les erreurs pour les systèmes qui différencient les fichiers textes et binaires comme Windows par exemple.

 

Lire un fichier partie par partie

PHP met à notre disposition plusieurs fonctions qui vont nous permettre de lire un fichier partie par partie :

  • La fonction fread() ;
  • La fonction fgets() ;
  • La fonction fgetc().

Lire un fichier jusqu’à un certain point avec fread()

La fonction fread() (abréviation de « file read » ou « lecture de fichier » en français) va prendre en arguments le fichier renvoyé par fopen() ainsi qu’un nombre qui correspond aux nombres d’octets du fichier qui doivent être lus.

Pour lire le fichier entièrement, on peut utiliser la fonction filesize() en lui passant le nom du fichier qu’on souhaite lire en deuxième argument de fread(). En effet, filesize() renvoie la taille d’un fichier. Cela va donc nous permettre de lire entièrement un fichier à condition de commencer la lecture au début.

Illustrons cela avec un exemple concret. Pour cet exemple, je réutilise le fichier test.txt créé dans la leçon précédente.

<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP & MySQL</title>
        <meta charset="utf-8">
        <link rel="stylesheet" href="cours.css">
    </head>
    
    <body>
        <h1>Titre principal</h1>
        <?php       
            $ressource = fopen('test.txt', 'rb');
            echo fread($ressource, filesize('test.txt'));
        ?>
        <p>Un paragraphe</p>
    </body>
</html>

 

On utilise les fonctions fopen et fread pour ouvrir et lire un fichier en PHP

Ici, on commence par utiliser fopen() pour lire notre fichier et on récupère la ressource renvoyée par la fonction dans une variable $ressource.

On passe ensuite le contenu de notre variable à fread() et on lui demande de lire le fichier jusqu’au bout en lui passant la taille exacte du fichier obtenue avec filesize().

Finalement, on affiche le résultat renvoyé par fread() grâce à une structure echo.

Lire un fichier ligne par ligne avec fgets()

La fonction fgets() va nous permettre de lire un fichier ligne par ligne. On va passer le résultat renvoyé par fopen() en argument de fgets() et à chaque nouvel appel de la fonction, une nouvelle ligne du fichier va pouvoir être lue.

On peut également préciser de manière facultative un nombre en deuxième argument de fgets() qui représente un nombre d’octets. La fonction lira alors soit le nombre d’octets précisé, soit jusqu’à la fin du fichier, soit jusqu’à arriver à une nouvelle ligne (le premier des trois cas qui va se présenter). Si aucun nombre n’est précisé, fgets() lira jusqu’à la fin de la ligne.

Notez que si on précise un nombre d’octets maximum à lire inférieur à la taille de notre ligne et qu’on appelle successivement fgets(), alors la fin de la ligne courante sera lue lors du deuxième appel de fgets().

<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP & MySQL</title>
        <meta charset="utf-8">
        <link rel="stylesheet" href="cours.css">
    </head>
    
    <body>
        <h1>Titre principal</h1>
        <?php       
            $ressource = fopen('test.txt', 'rb');
            
            //Lit les 30 premiers caractères du fichier
            echo 'Premier appel : ' .fgets($ressource, 30). '<br>';
            
            //Lit le reste de la première ligne
            echo 'Deuxième  appel : ' .fgets($ressource). '<br>'; 
            
            //Lit la deuxième ligne du fichier
            echo 'Troisième appel : ' .fgets($ressource). '<br>';
        ?>
        <p>Un paragraphe</p>
    </body>
</html>

 

On utilise la fonction fgets en PHP pour manipuler et lire un fichier ligne par ligne en PHP

Lire un fichier caractère par caractère avec getc()

Dans certains cas, il va également être intéressant de lire un fichier caractère par caractère notamment pour récupérer un caractère en particulier ou pour arrêter la lecture lorsqu’on arrive à un certain caractère.

Pour faire cela, nous allons cette fois-ci utiliser la fonction fgetc(). Cette fonction va s’utiliser exactement comme fgets(), et chaque nouvel appel à la fonction va nous permettre de lire un nouveau caractère de notre fichier. Notez que les espaces sont bien entendus considérés comme des caractères.

<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP & MySQL</title>
        <meta charset="utf-8">
        <link rel="stylesheet" href="cours.css">
    </head>
    
    <body>
        <h1>Titre principal</h1>
        <?php       
            $ressource = fopen('test.txt', 'rb');
            
            //Lit le premier caractère du fichier
            echo 'Premier appel : ' .fgetc($ressource). '<br>';
            
            //Lit le deuxième caractère
            echo 'Deuxième  appel : ' .fgetc($ressource). '<br>'; 
            
            //Lit le troisième caractère
            echo 'Troisième appel : ' .fgetc($ressource). '<br>';
        ?>
        <p>Un paragraphe</p>
    </body>
</html>

 

On utilise la fonction fgetc pour manipuler et lire un fichier caractère par caractère en PHP

 

Trouver la fin d’un fichier de taille inconnue

Dans ce cours, nous travaillons pour l’instant sur des exemples simples. Ici, par exemple, nous avons nous mêmes créé un fichier pour effectuer différentes opérations dessus.

En pratique, cependant, nous utiliserons généralement les fichiers pour stocker des informations non connues à l’avance. Dans ce cas-là, il est impossible de prévoir à l’avance la taille de ces fichiers et on risque donc de ne pas pouvoir utiliser les fonctions fgets() et fgetc() de manière optimale.

Il existe plusieurs moyens de déterminer la taille ou la fin d’un fichier. La fonction filesize(), par exemple, va lire la taille d’un fichier. Dans le cas présent, cependant, nous cherchons plutôt à déterminer où se situe la fin d’un fichier (ce qui n’est pas forcément équivalent à la taille d’un fichier à cause de la place du curseur, notion que nous allons voir en détail par la suite).

La fonction PHP feof() (« eof » signifie « end of the file » ou « fin du fichier ») va nous permettre de savoir si la fin d’un fichier a été atteinte ou pas. Dès que la fin d’un fichier est atteinte, cette fonction va renvoyer la valeur true. Avant cela, elle renverra la valeur false. On va donc pouvoir utiliser cette fonction pour boucler dans un fichier de taille inconnue.

<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP & MySQL</title>
        <meta charset="utf-8">
        <link rel="stylesheet" href="cours.css">
    </head>
    
    <body>
        <h1>Titre principal</h1>
        <?php       
            $res = fopen('test.txt', 'rb');
            
            /*Tant que la fin du fichier n'est pas atteninte, c'est-à-dire
             *tant que feof() renvoie FALSE (= tant que !feof() renvoie TRUE)
             *on echo une nouvelle ligne du fichier*/
            while(!feof($res)){
                $ligne = fgets($res);
                echo 'La ligne "' .$ligne. '" contient
                ' .strlen($ligne). ' caractères <br>';
            }
        ?>
        <p>Un paragraphe</p>
    </body>
</html>

 

On utilise la fonction feof pour trouver la fin d'un fichier en PHP

Ici, tant que la fin du fichier n’est pas atteinte, on affiche une nouvelle ligne de notre fichier et on calcule le nombre de caractères de la ligne grâce à la fonction strlen(), abréviation de « string length » ou « longueur de la chaine » en français.

Notez qu’ici le fait de retourner à la ligne compte comme un caractère et que la fonctions fgets() s’arrête après ce passage à la ligne. C’est la raison pour laquelle lorsqu’on compte le nombre de caractères de nos lignes, on a un caractère de plus que ce à quoi on pouvait s’attendre (sauf pour la dernière).

 

La place du curseur interne ou pointeur de fichier

La position du curseur (ou « pointeur de fichier ») va impacter le résultat de la plupart des manipulations qu’on va pouvoir effectuer sur les fichiers. Il est donc essentiel de toujours savoir où se situe ce pointeur et également de savoir comment le bouger.

Le curseur ou pointeur est l’endroit dans un fichier à partir duquel une opération va être faite. Pour donner un exemple concret, le curseur dans un document Word, dans un champ de formulaire ou lorsque vous effectuez une recherche Google ou tapez une URL dans votre navigateur correspond à la barre clignotante.

Ce curseur indique l’emplacement à partir duquel vous allez écrire votre requête ou supprimer un caractère, etc. Le curseur dans les fichiers va être exactement la même chose à la différence qu’ici on ne peut pas le voir visuellement.

Le mode d’ouverture choisi va être la première chose qui va influer sur la position du pointeur. En effet, selon le mode choisi, le pointeur de fichier va se situer à une place différente et va pouvoir ou ne va pas pouvoir être déplacé :

Mode utiliséPosition du pointeur de fichier
r / r+Début du fichier
a / a+Fin du fichier
w / w+Début du fichier
x / x+Début du fichier
c / c+Début du fichier

Ensuite, vous devez également savoir que certaines fonctions vont modifier la place du curseur à chaque exécution. Cela va par exemple être le cas des fonctions fgets() et fgetc() qui servent à lire un fichier ligne par ligne ou caractère par caractère.

En effet, la première fois qu’on appelle fgets() par exemple, le pointeur est généralement au début de notre fichier et c’est donc la première ligne de notre fichier est lue par défaut. Cependant, lors du deuxième appel à cette fonction, c’est bien la deuxième ligne de notre fichier qui va être lue.

Ce comportement est justement dû au fait que la fonction fgets() déplace le pointeur de fichier du début de la première ligne au début de la seconde ligne dans ce cas précis.

Pour savoir où se situe notre pointeur de fichier, on peut utiliser la fonction ftell() qui renvoie la position courante du pointeur. Nous allons devoir lui passer la valeur renvoyée par fopen() pour qu’elle fonctionne correctement.

<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP & MySQL</title>
        <meta charset="utf-8">
        <link rel="stylesheet" href="cours.css">
    </head>
    
    <body>
        <h1>Titre principal</h1>
        <?php       
            $res = fopen('test.txt', 'rb');
            
            while(!feof($res)){
              echo 'Le pointeur est au niveau du caractère ' .ftell($res). '<br>';
              $ligne = fgets($res);
              echo 'La ligne "' .$ligne. '" contient
              ' .strlen($ligne). ' caractères <br><br>';
            }
        ?>
        <p>Un paragraphe</p>
    </body>
</html>

 

On utilise la fonction PHP ftell pour retourner la position du pointeur dans un fichier

 

Déplacer le curseur manuellement

Pour commencer la lecture d’un fichier à partir d’un certain point, ou pour écrire dans un fichier à partir d’un endroit précis ou pour toute autre manipulation de ce type, nous allons avoir besoin de contrôler la position du curseur. Pour cela, nous allons pouvoir utiliser la fonction fseek().

Cette fonction va prendre en arguments l’information renvoyée par fopen() ainsi qu’un nombre correspondant à la nouvelle position en octets du pointeur.

La nouvelle position du pointeur sera par défaut calculée par rapport au début du fichier). Pour modifier ce comportement et faire en sorte que le nombre passé s’ajoute à la position courante du curseur, on peut ajouter la constante SEEK_CUR en troisième argument de fseek().

Notez cependant que si vous utilisez les modes a et a+ pour ouvrir votre fichier, utiliser la fonction fseek() ne produira aucun effet et votre curseur se placera toujours en fin de fichier.

<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP & MySQL</title>
        <meta charset="utf-8">
        <link rel="stylesheet" href="cours.css">
    </head>
    
    <body>
        <h1>Titre principal</h1>
        <?php       
          $res = fopen('test.txt', 'rb');
            
          echo 'Le pointeur est derrière le caractère ' .ftell($res). '<br>';
          echo 'Le caractère ' .(ftell($res) + 1). ' est un ' .fgetc($res). '<br>';
          echo 'Le pointeur est derrière le caractère ' .ftell($res). '<br>';
          fseek($res, 20);
          echo 'Le pointeur est derrière le caractère ' .ftell($res). '<br>';
          echo 'Le caractère ' .(ftell($res) + 1). ' est un ' .fgetc($res). '<br>';
          echo 'Le pointeur est derrière le caractère ' .ftell($res). '<br>';
          fseek($res, 40, SEEK_CUR);
          echo 'Le pointeur est derrière le caractère ' .ftell($res). '<br>';
          echo 'Le caractère ' .(ftell($res) + 1). ' est un ' .fgetc($res). '<br>';
        ?>
        <p>Un paragraphe</p>
    </body>
</html>

 

On utilise la fonction PHP fseek pour déplacer le pointeur interne dans un fichier

 

Fermer un fichier

Pour fermer un fichier en PHP, nous utiliserons cette fois la fonction fclose().

On va une nouvelle fois passer le résultat renvoyé par fopen() en argument de cette fonction.

Notez que la fermeture d’un fichier n’est pas strictement obligatoire. Cependant, cela est considéré comme une bonne pratique : cela évite d’user inutilement les ressources de votre serveur.

<!DOCTYPE html>
<html>
    <head>
        <title>Cours PHP & MySQL</title>
        <meta charset="utf-8">
        <link rel="stylesheet" href="cours.css">
    </head>
    
    <body>
        <h1>Titre principal</h1>
        <?php       
          $res = fopen('test.txt', 'rb');
            
          echo fread($res, filesize('test.txt'));
          fclose($res);
        ?>
        <p>Un paragraphe</p>
    </body>
</html>

 

On utilise la fonction PHP fclose pour fermer un fichier

3 réflexions au sujet de “Ouvrir, lire et fermer un fichier en PHP”

  1. Bonjour,
    Excusez moi de vous poser cette question :
    avec :
    //Lit les 30 premiers caractères du fichier
    echo ‘Premier appel : ‘ .fgets($ressource, 30).  »;
    affiche :
    Dans cette première section,
    soit 27 caractères (ou octets) et non pas 30 comme l’argument du paramètre de fgets….
    Du coup je ne comprend pas l’ecart.

    Désolé, je ne suis pas du genre à poser des questions sans avoir cherché, et là je seche…

    Amicalement,

Laisser un commentaire