11- Les fichiers

Il est possible en PHP de créer des fichiers et des répertoires, de les supprimer, de les lire et d’écrire dedans. Attention à une chose néanmoins qui va considérablement vous compliquer la tâche : tout ce que vous créez avec apache est créé par défaut avec l’utilisateur linux www-data (à moins que vous ne changiez cela). Selon les droits de cet utilisateur et les droits de l’utilisateur avec qui vous voulez lire les fichiers ou dossiers créés, vous pouvez éventuellement avoir quelques problèmes de permissions.

Création d’un répertoire

La commande pour créer un répertoire avec PHP est comme sous linux, mkdir() :

bool mkdir ( string $pathname [, int $mode = 0777 [, bool $recursive = FALSE [, resource $context ]]] )

Vous pouvez donc choisir le chemin du dossier, ses permissions (le mode est en octal, tout comme sous linux), la récursivité (si vous créez a/b/c alors que b n’existe pas) et le context (type ressource). La création d’un dossier renvoie true ou false selon si la création a réussi ou non. Il est donc conseillé de créer un dossier dans une condition pour pouvoir prendre en compte le cas où cela ne marche pas.

Exemple :

if(!mkdir("foo/bar")){
   echo"Le dossier n'a pas pu être créé.";
}

Dans cet exemple, PHP tente de créer un dossier “bar” dans “foo” et écrit un message si cela n’a pas fonctionné.

Création d’un fichier

La création et l’écriture dans un fichier se font avec la fonction fopen(). Cette fonction (qui veut dire file open) permet d’ouvrir un fichier, ce qui sous-entends qu’il faut le refermer ensuite. Il faut donc, pour ouvrir, écrire, puis fermer un fichier, utiliser fopen(), fwrite() et fclose(). La fonction fopen attend en paramètre le chemin du fichier à ouvrir (une chaîne de caractère), et le mode (chaîne de caractère) que l’on veut utiliser (lecture seule, lecture et écriture, écriture seule…).

Les modes sont les suivants

  • r : Ouvre en lecture seule, et place le pointeur de fichier au début du fichier.
  • r+ : Ouvre en lecture et écriture, et place le pointeur de fichier au début du fichier.
  • w : Ouvre en écriture seule ; place le pointeur de fichier au début du fichier et réduit la taille du fichier à 0. Si le fichier n'existe pas, on tente de le créer.
  • w+ : Ouvre en lecture et écriture ; place le pointeur de fichier au début du fichier et réduit la taille du fichier à 0. Si le fichier n'existe pas, on tente de le créer.
  • a : Ouvre en écriture seule ; place le pointeur de fichier à la fin du fichier. Si le fichier n'existe pas, on tente de le créer. Dans ce mode, la fonction fseek() n'a aucun effet, les écritures surviennent toujours.
  • a+ : Ouvre en lecture et écriture ; place le pointeur de fichier à la fin du fichier. Si le fichier n'existe pas, on tente de le créer. Dans ce mode, la fonction fseek() n'affecte que la position de lecture, les écritures surviennent toujours.
  • x : Crée et ouvre le fichier en écriture seulement ; place le pointeur de fichier au début du fichier. Si le fichier existe déjà, fopen() va échouer, en retournant FALSE et en générant une erreur de niveau E_WARNING. Si le fichier n'existe pas, fopen() tente de le créer. Ce mode est l'équivalent des options O_EXCL|O_CREAT pour l'appel système open(2) sous-jacent.
  • x+ : Crée et ouvre le fichier pour lecture et écriture; le comportement est le même que pour 'x'.
  • c : Ouvre le fichier pour écriture seulement. Si le fichier n'existe pas, il sera crée, s'il existe, il n'est pas tronqué (contrairement à 'w') et l'appel à la fonction n'échoue pas (comme dans le cas de 'x'). Le pointeur du fichier est positionné au début. Ce mode peut être utile pour obtenir un verrou (voyez flock()) avant de tenter de modifier le fichier, utiliser 'w' pourrait tronquer le fichier avant d'obtenir le verrou (vous pouvez toujours tronquer grâce à ftruncate()).
  • c+ : Ouvre le fichier pour lecture et écriture, le comportement est le même que pour le mode 'c'.
  • e : Défini l'indicateur close-on-exec sur le descripteur de fichier ouvert. Disponible uniquement en PHP compilé sur les systèmes conforme POSIX.1-2008.

La fonction fwrite() prend en paramètre une ressource (un fichier ouvert), et une chaîne de caractère. Par exemple, si j’ai ouvert un fichier avec fopen(), je passe la ressource retournée et la chaîne que je veux écrire dans la fonction fwrite(). Enfin, je passe la ressource (aussi appelé handle, la poignée en anglais) dans la fonction fclose() qui fermera le fichier.

On peut également écrire directement dans un fichier avec la fonction file_put_contents(), ce qui revient exactement à utiliser fopen(), puis fwrite(), puis fclose().

La fonction file_put_contents() retourne le nombre de bits écrits OU false dans le cas où le fichier n’a pas pu être créé. De plus, si le fichier à écrire n’existe pas, elle le crée, et s’il existe déjà, elle l’écrase si l’option file_append n’est pas définie. Pour tester si une erreur survient à la création ou l’écriture, il faut donc utiliser l’opérateur d’égalité de type et de valeur.

Exemple d’écriture dans un fichier :

if(file_put_contents('test.txt', 'Salut je suis un développeur') === false){
   echo "Une erreur est survenue";
}

if(!file_put_contents('test.txt', 'Salut je suis un développeur')){
   echo "Une erreur est survenue";
}

Lecture d’un fichier

Il est possible de lire le contenu des fichiers avec la fonction file_get_contents(). Cette fonction retourne l’intégralité du contenu d’un fichier en chaîne de caractère que l’on peut stocker dans une variable. Cette fonction prend en paramètre un nom de fichier (le chemin du fichier en chaîne de caractères) et d’autres paramètres optionnels comme l’utilisation du chemin d’inclusion (http://php.net/manual/fr/ini.core.php#ini.include-path), le contexte (créé avec stream_context_create() ), l’offset (la position de départ de lecture) et la taille maximale des données à lire.

La valeur de retour est soit un string (les données), soit un booléen, qui sert à évaluer si l’on est arrivé à lire le fichier ou pas.

Exemple de lecture d’un fichier :

if(file_exists('test.txt')){
   $monTexte = file_get_contents('test.txt');
   echo "monTexte";
}
else{
   echo'Le fichier n\'existe pas';
}

Notez que l’on peut vérifier si un fichier ou un dossier existe avant de l’ouvrir pour éviter les éventuelles erreurs.

Vérification des types

Il est possible de vérifier si un fichier existe avec file_exists(). Néanmoins, comme sur Linux, tout est fichier (même les dossiers), on ne peut tester si un fichier existe et que c’est bien un fichier qu’en testant file_exists(), is_file() ou is_dir().