Le cahier de réclamations
Chaque client écrit sa remarque à la suite des autres, sans effacer les pages précédentes : c'est file_put_contents avec FILE_APPEND.
Lire et écrire des fichiers texte et CSV sur le serveur, recevoir un fichier envoyé par un formulaire ($_FILES, move_uploaded_file) en le contrôlant, le supprimer (unlink) et le proposer en téléchargement.
Les artisans de Souk Atlas veulent envoyer la photo de leurs produits, les clients laisser un avis, et le gérant télécharger la liste des commandes en CSV pour Excel. Toutes ces fonctions passent par des fichiers stockés sur le serveur, que PHP lit, écrit et déplace.
Le formulaire a enctype="multipart/form-data" et un champ type="file". Le visiteur choisit tajine.jpg.
$fichier = __DIR__ . '/compteur.txt';
$visites = file_exists($fichier) ? (int) file_get_contents($fichier) : 0;
$visites++;
file_put_contents($fichier, $visites);
echo "Visite n° $visites";
file_put_contents(__DIR__ . '/journal.txt', date('H:i') . " connexion\n", FILE_APPEND);
$lignes = file(__DIR__ . '/journal.txt', FILE_IGNORE_NEW_LINES); // un tableau, une case par ligne
D’autres fonctions utiles : file_exists, is_file, is_dir, filesize, mkdir, scandir (liste d’un dossier), copy, rename, unlink (supprimer).
$f = fopen(__DIR__ . '/commandes.csv', 'w');
fputcsv($f, ['numero', 'client', 'total'], ';');
fputcsv($f, [1042, 'Amina Benali', 330], ';');
fclose($f);
<form action="envoyer.php" method="post" enctype="multipart/form-data">
<input type="file" name="photo" accept="image/*">
<button>Envoyer</button>
</form>
Les contrôles indispensables, dans cet ordre :
$_FILES['photo']['error'] === UPLOAD_ERR_OK (sinon : pas de fichier, trop gros pour upload_max_filesize…) ;size) ;mime_content_type($tmp) ou finfo), pas l’extension ni le type annoncé, que le visiteur contrôle ;bin2hex(random_bytes(8)) . '.jpg'), jamais le nom d’origine tel quel.<?php // export.php
$fichier = __DIR__ . '/../prive/commandes.csv'; // hors de htdocs : pas d'accès direct
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="commandes-' . date('Y-m-d') . '.csv"');
header('Content-Length: ' . filesize($fichier));
readfile($fichier);
exit;
Pour supprimer : unlink($chemin) (renvoie true si c’est fait).
Chaque client écrit sa remarque à la suite des autres, sans effacer les pages précédentes : c'est file_put_contents avec FILE_APPEND.
On dépose un colis : l'agent le pose d'abord sur un comptoir provisoire (le dossier temporaire), vérifie le poids et le contenu, puis le range dans le bon casier (move_uploaded_file). S'il est refusé, le comptoir est vidé à la fermeture.
La page s'affichera ici.
Le navigateur demandera /index.php au serveur, qui exécutera le PHP et renverra du HTML.
Consignes 0 / 3
Le fichier produits.csv contient des lignes « nom;prix;stock » avec une ligne de titres. Affichez chaque produit avec fgetcsv.
<?php $f = fopen(__DIR__ . '/produits.csv', 'r'); fgetcsv($f, null, ';'); // on saute la ligne des titres while (($ligne = fgetcsv($f, null, ';')) !== false) { [$nom, $prix, $stock] = $ligne; echo htmlspecialchars($nom) . " : $prix DH ($stock en stock)<br>"; } fclose($f);
Écrivez le traitement d'un formulaire d'envoi de photo (champ photo) : vérifiez l'absence d'erreur, une taille de 2 Mo maximum, un type JPEG ou PNG, puis rangez le fichier dans uploads/ avec un nom unique.
<?php $f = $_FILES['photo'] ?? null; if (!$f || $f['error'] !== UPLOAD_ERR_OK) { exit("Envoi échoué."); } if ($f['size'] > 2 * 1024 * 1024) { exit("Fichier trop lourd (2 Mo maximum)."); } $type = mime_content_type($f['tmp_name']); // type réel, lu dans le fichier $extensions = ['image/jpeg' => 'jpg', 'image/png' => 'png']; if (!isset($extensions[$type])) { exit("Seules les images JPEG et PNG sont acceptées."); } $nom = bin2hex(random_bytes(8)) . '.' . $extensions[$type]; move_uploaded_file($f['tmp_name'], __DIR__ . '/uploads/' . $nom); echo "Photo enregistrée : uploads/$nom";
supprimer.php?fichier=abc.jpg doit supprimer uploads/abc.jpg. Écrivez-le sans permettre de supprimer un autre fichier du serveur.
<?php $nom = basename($_GET['fichier'] ?? ''); // retire tout chemin : ../config.php devient config.php $chemin = __DIR__ . '/uploads/' . $nom; if ($nom !== '' && is_file($chemin)) { unlink($chemin); echo "Supprimé."; } else { echo "Fichier introuvable."; }