logo Pierre AULAS
Les fichiers en php - Pierre Aulas
 Parcours  |   Réalisations  |   Cours  |   Chroniques  |   Divers
Les informations sur un fichier
Manipuler un fichier
Ouvrir un fichier
Lire un fichier
Fermer un fichier
Fonctions pour fichier
Manipuler un répertoire
Lire un répertoire
Distinguer un répertoire d'un fichier
Créer et supprimer un répertoire
Exercices
Solutions

Manipuler les répertoires et les fichiers

Avant de se lancer, comprenons bien à quoi sert la manipulation de fichier.

Le fichier texte est le mode de stockage quasi-universel de l'information numérique. Contrairement à ce que l'on croit parfois, c'est sous forme de fichiers textes que les bases de données stockent l'information.

Autrement dit quand vous consultez votre compte en banque ou que vous commandez un billet d'avion ou de train, vous ne faites rien d'autre que demander à une machine d'aller lire pour vous le contenu d'un fichier texte (en faisant quelques petites vérifications sur votre identité dans le cas de votre compte en banque).

Si vous êtes capable de manipuler des fichiers, vous êtes donc capables de créer vous-même votre propre système de base de donnée ou de stockage de l'information.
C'est par exemple ce que font la plupart des wiki qui pour des raisons de portabilité fonctionnent uniquement avec des fichiers textes, sans recours à aucun SGBD (système de gestion de base de donnée)

Bref, tout cela pour vous dire que ce chapitre, malgré les apparences, est absolument fondamental. Si vous êtes capable de lire un fichier, vous n'aurez aucune difficulté à vous connecter à une base de donnée (cela fonctionne sur le même principe).

1. Ce que l'on peut savoir sur un fichier

Dès que vous créez un fichier, même vide, celui-ci posséde déjà un grand nombre d'informations auxquelles php vous donne accès à travers une série de fonctions dont nous ne verrons ici que les plus courantes :

Exercice 1

Haut de page

2. Manipuler un fichier

Bien que php fournisse des fonctions qui permettent de passe outre, les manipulations de fichiers se font toujours en trois temps :

2.1 Ouvrir un fichier avec fopen()

$descFic = fopen(nomFichier, mode);

fopen() ouvre le fichier nomFichier et renvoie un descripteur qui peut ensuite être utilisé pour lire le contenu. Les modes d'ouverture sont les suivants :

Php autorise à combiner les modes comme par exemple rw. On peut également ajouter un b à la fin du mode pour indiquer qu'il s'agit d'un fichier au format binaire.
Le paramètre nomFichier peut être une URL complète commençant par http:// ou ftp://, suivi du chemin d'accès au fichier.
Lorsque ces accès nécessitent une identification standard, php permet d'écrire (sous réserve que dans php.ini allow_url soit à on): ftp://nomutilisateur:motdepasse@www.adresse.fr/monFichier.
Plus simplement: pour ouvrir le fichier "nomFichier" en lecture seule il vous suffit d'écrire:

$descFic = fopen("nomFichier", "r"); //J'ouvre le fichier nomFichier en mode lecture seule.

Et le truc à ne jamais oublier : toujours penser à refermer son fichier avant de partir (sans ça ça va vite être le bazar dans la mémoire de votre machine) de la manière suivante :

fclose($descFic); //Je ferme mon fichier.

Haut de page

2.2 Lire et écrire dans un fichier

2.2.1 Lire dans les régles de l'art

Php fournit plusieurs fonctions pour lire un fichier (dont certaines communes au langage C) :

$descFic = fopen ("nomFichier", "r");
while ($ligne = fread ($descFic, filesize("nomFichier")))
{
  print $ligne."
";
}
fclose ($descFic);

Tant que la fonction fread() renvoie une valeur, while est vérifié. On affiche le contenu renvoyé (c'est-à-dire une ligne). Lorsque fread() renvoie une valeur nulle, c'est que la fin du fichier est atteinte. On sort alors de la boucle while.

fgetc($descFic) renvoie un seul caractère du fichier

$descFic = fopen ("nomFichier", "r");
while (!feof($descFic))
{
  $char = fgetc ($descFic);
  print "$char";
}
fclose ($descFic);

On notera l'utilisation de la fonction feof($descFic) qui permet de tester si l'on a atteint la fin du fichier (feof signifie find end of file). Tous les fichiers possédent, en en-tête et en fin de fichier un caractère particulier qui indique qu'il s'agit du début du fichier ou de la fin de fichier. La fonction feof renvoie true lorsqu'elle rencontre le caractère « fin de fichier », dit également « end of file (eof) ».

Haut de page

2.2.2 Lire vite fait

Comme il est très courant que l'on veuille récupérer le contenu d'un fichier texte et qu'on veuille l'afficher, php fournit des fonctions qui font le travail à votre place, en vous dispensant même d'avoir recours à fopen() et fclose() :

file (nomFichier) charge tout le contenu de nomFichier dans un tableau, avec un élément par ligne. Charge ensuite à vous d'afficher le contenu de ce tableau (avec un boucle for ou foreach par exemple).

$tableau = file("nomFichier");
foreach ($tableau as $valeur)
  print $valeur;

La boucle foreach() se charge ici d'afficher le contenu du tableau $tableau dans lequel a été recueilli le contenu du fichier nomFichier.

readfile (nomFichier [, booléen]) se charge de tout : d'ouvrir le fichier, de le lire, de le fermer et d'en afficher le contenu. Et si vous mettez l'argument facultatif à 1, le fichier est recherché dans tous les répertoires définis par l'option include_path de php.ini.

readfile("nomFichier");

Si les lignes de textes que vous récupérez dans un fichier sont elles-mêmes un agrégat de champs séparés par des signes conventionnels (comme des ";" ou des ":"), rappelez vous qu'il existe une fonction explode(separateur, chaine) qui permet de récupérer chacun des champs dans un tableau.

$tableau = explode (" : ", $chaine);
foreach ($tableau as $valeur)
 print "$valeur<BR>";

Cette formule permet d'afficher chacun des éléments de $chaine séparé des autres par le séparateur " : " (attention: il y a un espace avant et après le ":").
Si vous avez déjà été amené à ouvrir le contenu d'une base de données en mode texte, l'usage des séparateurs pour organiser un contenu ne devrait pas vous surprendre.

Exercice 2

Haut de page

2.2.3 Ecrire dans les normes

Pour pouvoir écrire dans un fichier, la première condition est de l'ouvrir en mode écriture 'w' ou ajout 'a'.
Attention : lorsque vous ouvrez en mode écriture 'w' le contenu du fichier est écrasé.

fwrite($descFic, "chaîne à ajouter" [, longueur]) ou fputs($descFic, "chaîne à ajouter" [, longueur]) insèrent "chaîne à ajouter" dans le fichier désigné par le descripteur $descFic. longueur est un paramètre facultatif qui permet de limiter la taille de la chaîne insérée.

$descFic = fopen ("nomFichier", "a");
fwrite($descFic, "Desaix découvre la Haute-Egypte en 1802.", 10);
//Ajoute les 10 premiers caractères de la chaîne soit "Desaix déc", au fichier nomFichier.
fclose ($descFic);

2.3 Fermer un fichier avec fclose()

fclose($descFic);

La fonction fclose() permet de fermer l'accès à un fichier lorsque vous avez fini de le lire ou de le modifier.
Attention: c'est bien le descripteur obtenu à l'aide de la fonction fopen() qui doit être passé en paramètre à fclose() et non le nom du fichier lui-même.

Exercice 3

Exercice 4

Haut de page

2.4 Quelques fonctions utiles avec les fichiers

unlink (nomfichier)

unlink (nomfichier) permet de supprimer un fichier.

rename (nomfichier, nouveaunom)

rename (nomfichier, nouveaunom) permet de renommer un fichier.

copy (source, destination)

copy (source, destination) permet de copier un fichier.

require (nomFichier) ou include (nomFichier)

require (nomFichier) et include (nomFichier) permettent d'inclure le contenu de nomFichier dans un script.
Pour éviter que le contenu d'un fichier puisse être inclu deux fois par mégarde, utilisez les fonctions require_once() et include_once().

Haut de page

3. Manipuler des répertoires

3.1 Ouvrir, lire et fermer

Les répertoires se manipulant selon le même principe que les fichiers (ouverture/écriture/fermeture), j'indique ici directement les fonctions php qui correspondent à chacune des étapes.

$descRep = opendir (nomRépertoire) ouvre le répertoire nomRépertoire et renvoie un descripteur qui peut ensuite être ensuite utilisé pour lire le contenu.

readdir ($descRep) permet de lire ligne à ligne le contenu du répertoire

closedir ($descRep) ferme le répertoire

Exemple permettant d'afficher le contenu du répertoire courant :

$nomRep = ".";
$descRep = opendir ($nomRep);
while ($ligne = readdir($descRep))
{
  print $ligne;
}
closedir ($descRep);

Haut de page

3.2 Distinguer les répertoires des fichiers

Lorsque vous parcourez le contenu d'un répertoire, il peut être intéressant de distinguer fichiers et répertoires, les seconds étant susceptibles de contenir encore d'autres fichiers.
Il existe pour cela les fonctions is_file(nom) et is_dir(nom) qui testent si l'élément nom est un fichier ou un répertoire. Appliqué à l'exemple précédent cela pourrait nous donner :

$nomRep = ".";
$descRep = opendir ($nomRep);
while ($ligne = readdir($descRep))
{
 $id = (is_dir($ligne)) ? "Répertoire :" : "Fichier :" ;
 print $id." ".$ligne;
}
closedir ($descRep);

Ces lignes permettent d'afficher tous les éléments contenus dans le répertoire courant (désigné par "."). Les fichiers sont précédés de la chaîne "Fichier : " suivie de leur nom, les répertoires sont précédés de la chaîne "Répertoire"

Haut de page

3.3 Créer et supprimer un répertoire

mkdir (nomRépertoire, permissions (en octal)) créé un répertoire et lui définit les droits d'accès en octal, selon le modèle UNIX.

mkdir ("desaix", 0777); //Je créé un répertoire "desaix" avec tous les droits pour tout le monde

rmdir (nomRépertoire) supprime un répertoire s'il est vide.

chdir (nomRépertoire) positionne dans nomRépertoire.

Exemple :

//Créé 10 répertoires imbriqués les uns dans les autres
for ($i=0;$i<10;$i++)
{
  mkdir("repertoire", 0777);
  chdir("repertoire");
}

//Supprime les 10 répertoires
for ($i=0;$i<10;$i++)
{
  chdir("..");
  rmdir("repertoire");
}

Maintenant que vous connaissez les principales fonctions liées aux fichiers et aux répertoires, vous devriez être en mesure de comprendre le bout de code suivant.
Son principe est simple (mais sa mise en œuvre l'est beaucoup moins)  : il permet le parcours d'une arborescence et l'affichage de son contenu.

Haut de page

Exercices

Exercice 1

Ecrivez une fonction infoFichier() qui, si le document existe, indique s'il s'agit d'un fichier, quelle est sa taille et sa date de création (si vous avez des difficultés pour les dates, relisez le cours sur les dates).

Solution

Exercice 2

Soit le fichier suivant: archi.txt. Commencez par le télécharger et regardez son contenu.
Vous constatez qu'il est constitué de plusieurs lignes. Chacune de ces lignes est constituée de plusieurs champs contenant respectivement et dans cet ordre: Nom du bâtiment, date de construction, adresse, noms des architectes.

Centre universitaire René Cassin : 1990 : 17, rue Saint-Hippolyte : Jacques RIPAULT et Denise DUHART
Garde-meuble du mobilier national : 1934 : 1, rue Berbier du Mets : Auguste PERRET
Dortoirs de l'Armée du Salut : 1927 : 29, rue des Cordelières : LE CORBUSIER
Logements : 1987 : 106-112, bvd Auguste Blanqui : D. MAUFRAS
Ensemble de logements : 1935 : 75, bvd Blanqui : Agence d'architecture HBM
Tour Croulebarbe : 1960 : 33, rue Croulebarbe : Edouard ALBERT, Roger BOILEAU, LABOURDETTE
Grand écran : 1991 : place d'Italie : Kenzo TANGE, Michel MACARY, Xavier MENU

Vous remarquez que chacun de ces champs se distingue du précédent et du suivant par un séparateur, ici le " : ".

L'exercice consiste à faire afficher dans votre page html le contenu de ce fichier à l'intérieur d'un tableau similaire au tableau suivant:

Centre universitaire René Cassin199017, rue Saint-HippolyteJacques RIPAULT et Denise DUHART
Garde-meuble du mobilier national19341, rue Berbier du MetsAuguste PERRET
Ensemble de logements193575, bvd BlanquiAgence d'architecture HBM
Tour Croulebarbe196033, rue CroulebarbeEdouard ALBERT, Roger BOILEAU, LABOURDETTE
Grand écran1991place d'ItalieKenzo TANGE, Michel MACARY, Xavier MENU
Ensemble HBM1909165, bvd de l'HôpitalH. SAUVAGE et C. SARRAZIN
Habitations à bon marché1922-26137, boulevard de l'HôpitalJoseph CHARLET et F. PERRIN

Pour faire cet exercice, vous avez besoin de connaître les fonctions file() et explode() ainsi que le fonctionnement des boucles (si cela n'est pas acquis, relisez le cours sur les bases de Php).

Solution

Haut de page

Exercice 3

Cet exercice a pour but de vous faire construire, à côté de votre tableau d'affichage, un petit formulaire qui permette à l'utilisateur de rajouter des données à l'intérieur du fichier archi.txt.
Ce formulaire peut prendre par exemple l'allure suivante:

Type de batiment :
Date du batiment :
Adresse du batiment :
Auteur(s) du batiment :

dont le code est le suivant:

<FORM action="/monfichier.php" method="GET">
 Type de batiment : <INPUT type="text" name="batiment" size="20"><BR>
 Date du batiment : <INPUT type="text" name="date" size="20"><BR>
 Adresse du batiment : <INPUT type="text" name="adresse" size="20"><BR>
 Auteur(s) du batiment : <INPUT type="text" name="auteur" size="20"><BR><BR>
 <INPUT type="submit" value="Inserer">
</FORM>

A vous de réaliser le bout de script php capable de récupérer les données renvoyées par le formulaire et de les insérer dans le fichier "archi.txt" en respectant l'organisation de ce fichier (c'est-à-dire que chaque champs doit être séparé des autres par un " : ").

Solution

Haut de page

Exercice 4

Dernière étape: vous devez permettre à votre utilisateur de supprimer des enregistrements. Pour cela vous allez recourir à une nouvelle méthode: celle des liens en forme de requête GET.
Par exemple, si vous écrivez un lien de la manière suivante:
 <A href="mapage.php?suppr=2">Supprimer</A>
Non seulement l'utilisateur sera redirigé vers "mapage.php" en cliquant sur ce lien, mais il enverra en même temps à cette page, en méthode GET, une variable suppr contenant la valeur 2.
Vous constatez au passage qu'un formulaire n'est pas la seule manière de transmettre des informations à une page: un lien peut suffire.

Pour cet exercice: il faut dans un premier temps que vous modifiez votre fonction d'affichage pour qu'elle ajouter des liens Supprimer sur chacune des lignes comme présenté ci-dessous:

Centre universitaire René Cassin199017, rue Saint-HippolyteJacques RIPAULT et Denise DUHARTSupprimer
Garde-meuble du mobilier national19341, rue Berbier du MetsAuguste PERRETSupprimer
Ensemble de logements193575, bvd BlanquiAgence d'architecture HBMSupprimer
Tour Croulebarbe196033, rue CroulebarbeEdouard ALBERT, Roger BOILEAU, LABOURDETTESupprimer
Grand écran1991place d'ItalieKenzo TANGE, Michel MACARY, Xavier MENUSupprimer
Ensemble HBM1909165, bvd de l'HôpitalH. SAUVAGE et C. SARRAZINSupprimer
Habitations à bon marché1922-26137, boulevard de l'HôpitalJoseph CHARLET et F. PERRINSupprimer

Dans un second temps, écrivez le script php qui permet de supprimer l'enregistrement séléctionné par l'utilisateur.

Solution

Haut de page

Solutions

Exercice 1

Ecrivez une fonction infoFichier qui, si le document existe, indique s'il s'agit d'un fichier et quelle est sa taille.

function infoFichier ($fic)
{
  if (file_exists($fic)) //Je vérifie que le fichier existe
  {
    if (is_file($fic)) //Si c'est un fichier
      print "<I>$fic</I> est un fichier.<BR>"; //J'affiche que c'est un fichier
    print "$fic pèse ".filesize($fic).".<BR>"; //J'indique sa taille
    print "$fic a été créé le ".date("d/m/y", filectime($fic)).".<BR>"; //et sa date de création
  }
}

infoFichier("archi.txt");

Haut de page

Exercice 2

En en-tête de votre script (prenez l'habitude de bien distinguer vos scripts php, placés dans les en-têtes, de votre code HTML), vous pouvez écrire la fonction afficher() suivante:

function afficher($fichier, $separateur)
{
 $tab = file($fichier);
 print "<TABLE BORDER=\"1\">";
 foreach ($tab as $val)
 {
  print "<TR>";
  $sstab = explode($separateur, $val);
  foreach ($sstab as $ssval)
   print "<TD>$ssval</TD>";
  print "</TR>";
 }
 print "</TABLE>";
}

Il ne vous reste plus qu'à appeler votre fonction afficher() dans votre code html en lui passant les arguments qui conviennent:

<HTML>
<BODY>
  <? afficher("archi.txt", " : ") ?>
</BODY>
</HTML>

Haut de page

Exercice 3

Voici le script qu'il fallait écrire dans l'en-tête pour déclencher l'insertion des données fournies par l'utilisateur dans le formulaire (après avoir vérifié que des données avaient bien été fournies par l'utilisateur):

if (!empty($_GET)) //Je vérifie que des données ont bien été fournies par la méthode GET
{
 $separateur = " : ";
 $chaine = $_GET['batiment'];
 $chaine .= $separateur.$_GET['date'];
 $chaine .= $separateur.$_GET['adresse'];
 $chaine .= $separateur.$_GET['auteur']."\n"; //Je concatène petit à petit une chaîne de caractère
 $pFic = fopen ("archi.txt", 'a'); //J'ouvre mon fichier en mode ajout (en mode écriture j'effacerai son contenu)
 fputs ($pFic, $chaine); //Puis je l'insère dans mon fichier
 fclose ($pFic);
}

Haut de page

Exercice 4

Comme vous le constatez, votre fonction afficher() ne nécessitait pas beaucoup de modifications:

function afficher($fichier, $separateur)
{
  $tab = file($fichier);
  print "<TABLE BORDER=\"1\">";
  for($i=0;$i<count($tab);$i++)
  {
    print "<TR>";
    $sstab = explode($separateur, $tab[$i]);
    foreach ($sstab as $ssval)
      print "<TD>$ssval</TD>";
    print "<A href=\"".$_SERVER['PHP_SELF']."?suppr=".$i."\">Supprimer</A>";
    print "</TR>";
  }
  print "</TABLE>";
}

Pour le script de modification, nous avons choisi de l'écrire en trois temps :

if (!empty($_GET))
{
if (isset($_GET['suppr']))
{
 $pFic = fopen ("archi.txt", 'r');
 $tab = file("archi.txt");
 $chaine ="";
 for ($i = 0; $i<count($tab);$i++)
  $chaine .= ($i!=$_GET['suppr']) ? $tab[$i] : ""; //C'est ici qu'on supprime la ligne sélectionnée
 fclose ($pFic);
 $pFic = fopen ("archi.txt", 'w');
  fputs ($pFic, $chaine);
 fclose ($pFic);
}

Haut de page
Plan du site  |  Mentions légales  |  Crédits  |  Aide