Laisse pas traîner ton File
Introduction
En informatique et en développement, il y a beaucoup d'anglicismes. Tu as sûrement déjà entendu parler d'upload de fichier. "Uploader" un fichier désigne le fait de transférer un fichier, d'un ordinateur (local) vers un serveur. Par opposition au "download", qui désigne le fait de télécharger un fichier du distant vers le local. Le but de cette quête est, au file de l'eau, d'apprendre à effectuer un upload de fichiers en PHP.
🤓 À la fin de cette quête, tu seras capable de :
- ✅ mettre en place un upload de fichier simple
- ✅ gérer les problématiques de tailles et d'extensions
- ✅ afficher la photo de Homer sur son profil
Homer Simpson cherche sa moitié, son sucre d'orge, sa pomme d'amour !
Il decide de s'inscrire sur le site de rencontre SpringfieldWild dont tu es le développeur !!
Et voila, Homer, jeune et intrépride rockeur, voudrait ajouter sa plus belle photo.

Cette fonctionnalité est en cours de développement mais lui ne le sait pas.
Ta mission, créer un systeme d'upload simple. Grâce à toi Homer pourra ajouter sa photo !!
Go !
Comment fonctionne l'upload ?
Il arrive souvent de vouloir uploader une image ou un fichier sur un serveur, grâce à un formulaire.
Il existe une solution simple, PHP a pensé à tout pour réussir cette tâche.
Pour cela, tu as besoin d'un formulaire avec un champ type file et d'un script PHP pour le traitement de ce dernier .
Le formulaire
<form method="post" enctype="multipart/form-data">
<label for="imageUpload">Upload an profile image</label>
<input type="file" name="avatar" id="imageUpload" />
<button name="send">Send</button>
</form>
Un formulaire simple avec un champ de type file et un bouton pour le soumettre.
Explication
⚠️ L'attribut enctype="multipart/form-data" est obligatoire pour gérer correctement les fichiers uploadés via un formulaire, sans cet attribut l'upload ne fonctionnera pas.
<form action="" method="post" enctype="multipart/form-data">
Le champ de type file qui va t'aider à récupérer ton image (ou fichier) de ton pc/mac.
<input type="file" name="avatar" id="imageUpload" />
L'élément button qui va t'aider à envoyer l'image ou le fichier sélectionné vers ton serveur.
<button name="send">Send</button>
Le script
<?php
// Je vérifie que le formulaire est soumis, comme pour tout traitement de formulaire.
if($_SERVER["REQUEST_METHOD"] === "POST" ){
// chemin vers un dossier sur le serveur qui va recevoir les fichiers transférés (attention ce dossier doit être accessible en écriture)
$uploadDir = 'public/uploads/';
// le nom de fichier sur le serveur est celui du nom d'origine du fichier sur le poste du client (mais d'autres stratégies de nommage sont possibles)
$uploadFile = $uploadDir . basename($_FILES['avatar']['name']);
// on déplace le fichier temporaire vers le nouvel emplacement sur le serveur. Ça y est, le fichier est uploadé
move_uploaded_file($_FILES['avatar']['tmp_name'], $uploadFile);
}
Voici un exemple simple de script utilisé pour traiter les données d'un formulaire.Tu connaissais déjà $_GET et $_POST comme variable superglobale de PHP. Comme tu le vois, il en existe d'autres comme $_FILES et qui permet la gestion des fichiers.
Explication
Cette variable est un tableau de tableaux, qui prend en première clé le nom du/des champ(s) de type file du formulaire, et en seconde dimension un tableau de 5 éléments. Voici le code correspondant au formulaire écrit juste au dessus, pour le champ de type file portant le nom avatar :
-
$_FILES['avatar']['name']Contient le nom d'origine du fichier (sur le poste du client) -
$_FILES['avatar']['tmp_name']Contient le nom temporaire du fichier dans le dossier temporaire du système (sur le serveur) -
$_FILES['avatar']['type']Contient le type MIME du fichier (plus fiable que l'extension) -
$_FILES['avatar']['size']Contient la taille du fichier en octets -
$_FILES['avatar']['error']Contient le code de l'erreur (le cas échéant)
Pour finir, tu dois gérer l'enregistrement du fichier sur le serveur via la fonction move_uploaded_file()
Il faut bien comprendre que le fichier soumis dans le formulaire est tout d'abord déplacé dans le dossier /tmp du serveur, et que c'est la fonction move_uploaded_file() qui va finir l'upload en déplaçant le fichier temporaire vers sa destination finale.
Un petit schéma pour vous aider à ne pas perdre le file

Pour résumer, il faut :
-
construire un formulaire avec l'attribut
enctype="multipart/form-data"et un champ de typefile -
récupérer le fichier via la variable
$_FILESet vérifier que tout est conforme -
utiliser la fonction
move_uploaded_filepour copier définitivement le fichier sur le serveur (ou un autre emplacement en local)
Cet exemple, bien que fonctionnel, est très basique et non sécurisé. Les ressources suivantes vont t'apprendre comment gérer un upload sécurisé (et ne pas rester sur le file du rasoir), gérer les erreurs et détecter la taille et le type du fichier.
Un peu plus d'informations sur la gestion des erreurs d'upload
Cette page reprend et détaille un peu plus l'exemple présenté précédemment
Sécurise ton formulaire avec le php
<?php
// Je vérifie si le formulaire est soumis comme d'habitude
if($_SERVER['REQUEST_METHOD'] === "POST"){
// Securité en php
// chemin vers un dossier sur le serveur qui va recevoir les fichiers uploadés (attention ce dossier doit être accessible en écriture)
$uploadDir = 'public/uploads/';
// le nom de fichier sur le serveur est ici généré à partir du nom de fichier sur le poste du client (mais d'autre stratégies de nommage sont possibles)
$uploadFile = $uploadDir . basename($_FILES['avatar']['name']);
// Je récupère l'extension du fichier
$extension = pathinfo($_FILES['avatar']['name'], PATHINFO_EXTENSION);
// Les extensions autorisées
$authorizedExtensions = ['jpg','jpeg','png'];
// Le poids max géré par PHP par défaut est de 2M
$maxFileSize = 2000000;
// Je sécurise et effectue mes tests
/****** Si l'extension est autorisée *************/
if( (!in_array($extension, $authorizedExtensions))){
$errors[] = 'Veuillez sélectionner une image de type Jpg ou Jpeg ou Png !';
}
/****** On vérifie si l'image existe et si le poids est autorisé en octets *************/
if( file_exists($_FILES['avatar']['tmp_name']) && filesize($_FILES['avatar']['tmp_name']) > $maxFileSize)
{
$errors[] = "Votre fichier doit faire moins de 2M !";
}
/****** Si je n'ai pas d"erreur alors j'upload *************/
/**
TON SCRIPT D'UPLOAD
*/
}
Explication
Par défaut, l'upload de fichier en PHP est limité à 2Mo. Ceci est configurable dans le fichier php.ini via la directive upload_max_filesize. Quelques autres directives sont également intéressantes, même s'il n'est généralement pas utile de les modifier :
-
upload_max_filesize Taille maximale en octets d'un fichier à charger.
-
post_max_size Taille maximale d'un POST (il ne doit donc pas être inférieur à upload_max_filesize)
-
file_uploads Autorise ou non le chargement de fichiers par HTTP. Voir aussi les directives upload_max_filesize, upload_tmp_dir et post_max_size.
-
upload_tmp_dir Le répertoire temporaire utilisé pour stocker les fichiers lors du chargement. C'est le répertoire /tmp qui est utilisé par défaut sous les systèmes GNU/Linux
-
max_file_upload Le nombre maximum de fichiers pouvant être envoyés simultanément (cela sera utile pour l'upload multiple)
Il est bien entendu possible de limiter la taille de l'upload pour chaque formulaire (en plus de la gestion globale du php.ini). Pour cela, il faut vérifier la taille de chaque fichier uploadé, avec la fonction filesize() et autoriser ou non l'exécution de move_uploaded_file().
Pour vérifier si le type de fichier est autorisé (seulement des images par exemple), il est possible de vérifier si le type MIME (plus précis que l'extension) correspond à une liste prédéterminée, sinon l'upload sera refusé. Tu pourras utiliser pour cela, la fonction PHP mime_content_type.
Si l'on téléverse le fichier en conservant son nom d'origine, il y a un risque d'uploader 2 fichiers différents avec un nom identique. Dans ce cas, PHP écrasera le 1er fichier par le second, ce qui peut se révéler très problématique. Une solution, pour éviter cela, est de donner un nom unique aux fichiers uploadés. Ainsi il n'y a plus de risque de conflit. Plusieurs techniques existent. On peut citer par exemple la fonction uniqid() qui génère, comme son nom l'indique, un identifiant unique. Il ne faut cependant pas oublier de récupérer l'extension du fichier d'origine, en utilisant par exemple pathinfo().
Une courte vidéo reprenant ces notions, et implémentant un mécanisme simple de vérification de taille et d'extension :
Convertisseur Octet <=> Mega
💪 Challenge
Homer veut ajouter sa photo de profil
Voici un challenge qui va permettre la rencontre entre Homer et Marge !
- Commence par créér un fichier form.php
- Ecris le code du formulaire avec un input type file. Tu peux t'inspirer du formulaire plus haut.
- Ecris le code PHP pour gérer l'upload de ton image. Attention ! Ton code sera avant ton formulaire. Tu peux aussi t'inspirer du code plus haut.
- Sécurise ton formulaire avec la gestion du poids (1Mo max) et de l'extension (jpg, png, gif, webp). Tu peux aussi t'inspirer du code plus haut.
- Affiche sa photo, (tu peux, ajouter son nom, son prénom, son age en dur dans le code, ou encore mieux optionnellement, en ajoutant des champs dans ton form et en récupérant les informations de $_POST)
- Essaie également de faire en sorte que le nom de la photo soit unique.
Inspire-toi de cet exemple pour le rendu final

Dans tes projets, tu seras très souvent amené à gérer ainsi de l'upload de fichier. La plupart du temps, tu auras à sauvegarder les chemins vers ces fichiers dans une base de données, ce qui te permettra de lister par exemple les fichiers déjà présents, et de les supprimer si besoin.
- BONUS: Ajoute un bouton Delete permettant de supprimer le fichier. Pour cela, tu devras utiliser la fonction unlink de PHP qui permet de supprimer un fichier. Avant de supprimer un fichier, pense à vérifier qu'il existe bel et bien. La fonction file_exists pourra t'aider.
Critères de validation
- Un fichier form.php
- Le formulaire permet d'uploader la photo de Homer,
- Le script permettant de gérer l'upload
- Le script permettant de vérifier la taille et l'extension
- Si le poids de la photo dépasse 1Mo, l'upload est rejetée et un message d'erreur approprié apparaît
- la photo ayant une extension autre que
jpg,png,gifouwebpest rejetée, un message d'erreur approprié apparaît - La photo uploadée doit avoir un nom unique !
Ressources partagées sur cette quête
- Comment upload une image en PHP (français)https://www.youtube.com/watch?v=JxgulzYe5W0&t=1270s