Kodokon kodokon.com

Fichiers : lire, écrire, uploader, JSON

Lisez et écrivez des fichiers, journalisez les événements, acceptez des uploads sans risque et stockez vos données en JSON.

10 min · 3 questions

Ouvrir cette leçon dans Kodokon

Lire un fichier tient en une fonction : file_get_contents() renvoie tout le contenu en une chaîne, file() le découpe en tableau de lignes. Avant de lire, vérifiez l'accès avec is_readable() : un chemin cassé renverrait false accompagné d'un avertissement.

PHP
<?php

declare(strict_types=1);

$path = __DIR__ . '/notes.txt';

if (!is_readable($path)) {
    exit("Fichier introuvable ou illisible.");
}

$content = (string) file_get_contents($path);
echo nl2br(htmlspecialchars($content, ENT_QUOTES));

$lines = file(
    $path,
    FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES
);
echo count($lines) . " ligne(s) non vide(s)";
Lecture complète, puis ligne par ligne, du même fichier.

Pour écrire, file_put_contents() remplace tout le contenu par défaut. Deux drapeaux changent la donne : FILE_APPEND ajoute à la fin au lieu d'écraser, LOCK_EX pose un verrou exclusif pour que deux requêtes simultanées ne mélangent pas leurs écritures. C'est la recette d'un journal (log) applicatif minimal.

PHP
<?php

declare(strict_types=1);

$logFile = __DIR__ . '/app.log';

$line = sprintf(
    "[%s] Nouvelle commande de %s\n",
    date('Y-m-d H:i:s'),
    'alice@example.com'
);

file_put_contents(
    $logFile,
    $line,
    FILE_APPEND | LOCK_EX
);

echo "Événement journalisé.";
Un journal applicatif fiable en quelques lignes.

L'upload de fichier mérite une vigilance particulière. Le formulaire doit déclarer enctype="multipart/form-data", puis PHP décrit le fichier reçu dans $_FILES. Validez tout : le code d'erreur, la taille, et le type réel détecté par finfo - jamais l'extension ni le type annoncés par le navigateur. Enfin, seul move_uploaded_file() doit déplacer le fichier temporaire.

PHP
<?php

declare(strict_types=1);

$maxSize = 2 * 1024 * 1024;
$file = $_FILES['avatar'] ?? null;

if ($file === null || $file['error'] !== UPLOAD_ERR_OK) {
    exit("Aucun fichier valide reçu.");
}

if ($file['size'] > $maxSize) {
    exit("Fichier trop lourd (2 Mo max).");
}

$info = new finfo(FILEINFO_MIME_TYPE);
$mime = $info->file($file['tmp_name']);
$allowed = ['image/jpeg' => 'jpg', 'image/png' => 'png'];

if (!isset($allowed[$mime])) {
    exit("Format non autorisé.");
}

$name = bin2hex(random_bytes(8));
$target = __DIR__ . '/uploads/' . $name
    . '.' . $allowed[$mime];

move_uploaded_file($file['tmp_name'], $target);
echo "Image enregistrée.";
upload.php : taille, type réel et nom de fichier maîtrisés.

Le format JSON est le pont naturel entre PHP et le reste du monde : json_encode() sérialise un tableau, json_decode() fait l'inverse. Passez true en deuxième argument pour obtenir des tableaux associatifs, et le drapeau JSON_THROW_ON_ERROR pour transformer un JSON malformé en exception claire plutôt qu'en null silencieux.

PHP
<?php

declare(strict_types=1);

$path = __DIR__ . '/tasks.json';

$json = is_readable($path)
    ? (string) file_get_contents($path)
    : '[]';

$tasks = json_decode(
    $json,
    true,
    512,
    JSON_THROW_ON_ERROR
);

$tasks[] = [
    'title' => 'Relire la leçon',
    'done' => false,
];

file_put_contents(
    $path,
    json_encode(
        $tasks,
        JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE
    ),
    LOCK_EX
);

echo count($tasks) . " tâche(s) enregistrée(s)";
Un mini-stockage de données : lire, modifier, réécrire.

Quiz de validation

Vérifiez que vous avez bien retenu les points clés de cette leçon.

  1. Que fait le drapeau FILE_APPEND passé à file_put_contents() ?
    • Il ajoute le contenu à la fin du fichier au lieu de l'écraser
    • Il crée le dossier parent s'il n'existe pas
    • Il verrouille le fichier pendant l'écriture
  2. Pourquoi ne faut-il pas se fier à $_FILES['avatar']['type'] pour contrôler un upload ?
    • Cette clé n'existe que sur certains serveurs
    • Elle ne fonctionne que pour les images
    • Cette valeur est envoyée par le navigateur et peut être falsifiée ; il faut détecter le type réel avec finfo
  3. Que change le deuxième argument true dans json_decode($json, true) ?
    • Le décodage lève une exception en cas d'erreur
    • Les objets JSON deviennent des tableaux associatifs PHP au lieu d'objets stdClass
    • Les clés sont converties en majuscules