Module 2Programmer en PHP
Chapitre 5 sur 11
Traiter les données en PHP
Manipuler les tableaux, lire et écrire des fichiers, CSV et JSON, gérer l'envoi et le téléchargement de fichiers.
- ≈ 105 min
- 3 leçons
- 1 vidéo
- 3 exercices
Module 2Programmer en PHP
Chapitre 5 sur 11
Manipuler les tableaux, lire et écrire des fichiers, CSV et JSON, gérer l'envoi et le téléchargement de fichiers.
Objectifs
Avec ce chapitre, tu sauras…
fopen, fgets, file_get_contents, file_put_contents) ;$_FILES, sa suppression et son téléchargement.Leçon 1
Tableau: Tableaux indexés et associatifs
| Type | Clés | Exemple |
|---|---|---|
| indexé (simple) | des entiers à partir de 0 | $villes = ['Rabat', 'Fès', 'Tanger']; |
| associatif | des chaînes | $stagiaire = ['nom' => 'Benali', 'age' => 20]; |
| multidimensionnel | un tableau de tableaux | une liste de stagiaires, chacun étant un tableau associatif |
<?php
$villes = ['Rabat', 'Fès', 'Tanger']; // syntaxe courte (ou array('Rabat', ...))
echo $villes[0]; // Rabat
$villes[] = 'Agadir'; // ajoute à la fin
echo count($villes); // 4
$stagiaire = [
'nom' => 'Benali',
'prenom' => 'Sara',
'age' => 20,
];
$stagiaire['ville'] = 'Casablanca'; // ajoute une clé
unset($stagiaire['age']); // supprime une clé
echo $stagiaire['prenom']; // Sara
$promo = [
['nom' => 'Benali', 'moyenne' => 15.5],
['nom' => 'Saidi', 'moyenne' => 12.25],
['nom' => 'Alaoui', 'moyenne' => 17],
];
echo $promo[2]['nom']; // AlaouiParcourir un tableau
<?php
foreach ($villes as $ville) {
echo "$ville\n";
}
foreach ($stagiaire as $cle => $valeur) {
echo "$cle : $valeur\n";
}
foreach ($promo as $i => $s) {
echo ($i + 1) . ". {$s['nom']} : {$s['moyenne']}\n";
}| Fonction | Rôle | Exemple avec $t = [3, 1, 2] |
|---|---|---|
count($t) | nombre d'éléments | 3 |
in_array($x, $t) | la valeur existe ? | in_array(2, $t) → true |
array_search($x, $t) | la clé de la valeur (ou false) | array_search(2, $t) → 2 |
array_key_exists($k, $t), isset($t[$k]) | la clé existe ? | |
array_keys, array_values |
| Fonction | Trie… | Garde les clés ? |
|---|---|---|
sort / rsort | par valeur, croissant / décroissant | non (réindexe) |
asort / arsort | par valeur | oui |
ksort / krsort | par clé | oui |
usort($t, fn) | selon une fonction de comparaison | non |
| Opérateur | Rôle |
|---|---|
$a + $b | union : ajoute les clés de $b absentes de $a |
$a == $b | mêmes paires clé/valeur |
$a === $b | mêmes paires, même ordre et mêmes types |
[...$a, ...$b] | décomposition (fusion d'un tableau indexé) |
Vidéo · À regarder
ENPHP Full Course 2025 - Learn PHP from Scratch
Dani Krossing · YouTube
Leçon 2
Mode de fopen | Lecture | Écriture | Si le fichier existe | S'il n'existe pas |
|---|---|---|---|---|
'r' | oui | non | lecture depuis le début | erreur |
'r+' | oui | oui | depuis le début | erreur |
Leçon 3
$_FILES['photo'][…] | Contenu |
|---|---|
'name' | le nom d'origine du fichier chez le client |
'type' | le type MIME annoncé par le navigateur (non fiable) |
'size' | la taille en octets |
'tmp_name' |
1$t[] = 'x'; …
2Pour trier un tableau associatif par valeur en gardant les clés :
3array_column($promo, 'nom') renvoie…
4Le mode de fopen qui ajoute à la fin d'un fichier est…
5Un formulaire d'envoi de fichier doit avoir…
6Pour déplacer le fichier temporaire reçu :
7json_decode($texte, true) renvoie…
L'essentiel du chapitre
[...], associatifs ['cle' => valeur], multidimensionnels ; $t[] = x ajoute ; "{$t['cle']}" dans une chaîne.count, in_array, array_search, array_keys, array_column, array_merge, array_sum, max ; tris sort, asort, ksort, usort ; array_filter, array_map, array_reduce.file_get_contents, file_put_contents(…, FILE_APPEND), file() ; fopen (modes r, w, a, x), fgets, fwrite, fclose ; CSV fputcsv / fgetcsv ; JSON json_encode / json_decode(…, true).method="post" + enctype="multipart/form-data" ; $_FILES ; vérifier taille et vrai type, renommer, move_uploaded_file.unlink, téléchargement Content-Disposition: attachment + readfile ; basename() contre la traversée de répertoire.array_push, array_pop | ajouter / retirer à la fin |
array_unshift, array_shift | ajouter / retirer au début |
array_merge($a, $b) | fusionner |
array_slice($t, $debut, $n) | extraire une partie |
array_sum, array_product | somme, produit | array_sum($t) → 6 |
max, min | maximum, minimum | max($t) → 3 |
array_unique | supprimer les doublons |
array_column($promo, 'nom') | une colonne d'un tableau de tableaux | ['Benali', 'Saidi', 'Alaoui'] |
'w'| non |
| oui |
| vidé |
| créé |
'a' | non | oui | écriture à la fin | créé |
'x' | non | oui | erreur | créé |
'error' | le code d'erreur : UPLOAD_ERR_OK (0) si tout va bien |
Dans une chaîne entre guillemets doubles, "$s[nom]" fonctionne mais "$s['nom']" provoque une erreur de syntaxe. Écris "{$s['nom']}" avec des accolades : cela marche dans tous les cas, y compris pour "{$promo[0]['nom']}".
Tableau: Les fonctions essentielles
Tableau: Trier
<?php
usort($promo, fn($a, $b) => $b['moyenne'] <=> $a['moyenne']);
echo $promo[0]['nom']; // Alaoui (17)
$notes = ['HTML' => 15, 'CSS' => 13, 'JS' => 17];
arsort($notes); // ['JS' => 17, 'HTML' => 15, 'CSS' => 13]Filtrer et transformer
<?php
$moyennes = array_column($promo, 'moyenne', 'nom'); // ['Alaoui' => 17, 'Benali' => 15.5, 'Saidi' => 12.25]
$admis = array_filter($moyennes, fn($m) => $m >= 14); // garde les clés : ['Alaoui' => 17, 'Benali' => 15.5]
$sur100 = array_map(fn($m) => $m * 5, $moyennes); // ['Alaoui' => 85, 'Benali' => 77.5, 'Saidi' => 61.25]
$total = array_reduce($moyennes, fn($acc, $m) => $acc + $m, 0); // 44.75Les tableaux en PHP (en anglais).
Les fonctions simples
<?php
file_put_contents('journal.txt', "Connexion de Sara\n", FILE_APPEND); // ajoute à la fin
$contenu = file_get_contents('journal.txt'); // tout le fichier dans une chaîne
$lignes = file('journal.txt', FILE_IGNORE_NEW_LINES); // un tableau, une ligne par case
echo file_exists('journal.txt') ? filesize('journal.txt') . ' octets' : 'absent';Tableau: fopen, fgets, fwrite, fclose
Le chargement (upload)
<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="photo" accept="image/png, image/jpeg">
<button>Envoyer</button>
</form>method="post" et enctype="multipart/form-data". Sans enctype, le navigateur n'envoie que le nom du fichier, pas son contenu.
Écris stagiaires.php qui lit un fichier stagiaires.csv (nom, prénom, filière, moyenne) et affiche un tableau HTML trié par moyenne décroissante, avec la moyenne générale de la promotion et le nombre d'admis (moyenne ≥ 10). Ajoute un formulaire d'import qui remplace le fichier CSV par un fichier envoyé (CSV uniquement, 1 Mo maximum).
<?php
$notes = ['Ali' => 12, 'Sara' => 17, 'Nour' => 9, 'Omar' => 14];
arsort($notes);
echo implode(', ', array_keys($notes)), "\n";
$admis = array_filter($notes, fn($n) => $n >= 10);
echo count($admis), ' ', array_sum($admis) / count($admis), "\n";
echo array_search(9, $notes), ' ', max($notes), "\n";Crée livre_or.php : un formulaire (pseudo, message) qui ajoute chaque message, avec la date, à un fichier messages.json (un tableau d'objets). Sous le formulaire, affiche tous les messages, du plus récent au plus ancien, en échappant le texte. Refuse un pseudo ou un message vide.
<?php
$f = fopen('journal.txt', 'r');
if ($f) {
while (($ligne = fgets($f)) !== false) { // fgets lit une ligne
echo htmlspecialchars($ligne) . '<br>';
}
fclose($f); // toujours refermer
}CSV et JSON
<?php
// CSV : lisible dans Excel
$f = fopen('stagiaires.csv', 'w');
fputcsv($f, ['nom', 'prenom', 'moyenne']); // ligne d'en-tête
fputcsv($f, ['Benali', 'Sara', 15.5]);
fputcsv($f, ['Saidi', 'Ali', 12.25]);
fclose($f);
$f = fopen('stagiaires.csv', 'r');
$entete = fgetcsv($f);
while (($ligne = fgetcsv($f)) !== false) {
$s = array_combine($entete, $ligne); // ['nom' => 'Benali', ...]
echo "{$s['prenom']} {$s['nom']}\n";
}
fclose($f);
// JSON : idéal pour échanger avec JavaScript (M105) ou une API (chapitre 10)
file_put_contents('promo.json', json_encode($promo, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
$promo2 = json_decode(file_get_contents('promo.json'), true); // true : tableaux associatifsLes fichiers conviennent pour des journaux, des exports, une configuration, de petites données. Dès que plusieurs utilisateurs modifient les données en même temps, qu'il faut chercher, trier ou relier des informations, on utilise une base de données (chapitre 7).
<?php
$dossier = __DIR__ . '/uploads/';
$autorises = ['image/jpeg' => 'jpg', 'image/png' => 'png'];
if (!isset($_FILES['photo']) || $_FILES['photo']['error'] !== UPLOAD_ERR_OK) {
exit('Erreur lors de l\'envoi.');
}
if ($_FILES['photo']['size'] > 2 * 1024 * 1024) {
exit('Fichier trop lourd (2 Mo maximum).');
}
$type = mime_content_type($_FILES['photo']['tmp_name']); // le VRAI type, lu dans le fichier
if (!isset($autorises[$type])) {
exit('Seules les images JPEG et PNG sont acceptées.');
}
$nom = bin2hex(random_bytes(8)) . '.' . $autorises[$type]; // un nom aléatoire et sûr
if (move_uploaded_file($_FILES['photo']['tmp_name'], $dossier . $nom)) {
echo 'Photo enregistrée : ' . htmlspecialchars($nom);
}Un attaquant peut envoyer un script pirate.php renommé photo.jpg, ou falsifier le type annoncé. Les règles : vérifier la taille et le vrai type (mime_content_type, getimagesize) ; renommer le fichier avec un nom généré ; n'accepter que des extensions choisies par toi ; si possible, stocker les fichiers hors du dossier public.
Supprimer et télécharger
<?php
$fichier = __DIR__ . '/uploads/' . basename($_GET['f'] ?? ''); // basename : empêche ../../
if (is_file($fichier)) {
unlink($fichier);
}<?php
$fichier = __DIR__ . '/documents/' . basename($_GET['f'] ?? '');
if (!is_file($fichier)) {
http_response_code(404);
exit('Fichier introuvable.');
}
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($fichier) . '"');
header('Content-Length: ' . filesize($fichier));
readfile($fichier); // envoie le contenu du fichier
exit;Si tu écris unlink('uploads/' . $_GET['f']), un visiteur peut demander ?f=../config.php et supprimer ton fichier de configuration. basename() ne garde que le nom du fichier, sans aucun dossier : c'est la parade minimale contre la traversée de répertoire (chapitre 8).