Ressources pour développeur web

Théme de la semaine : Démo CSS

Upload d’image sécurisé en PHP : Tutoriel + Code complet

Temps de lecture estimé : 7 minutes
Accueil PHP 8 Upload d’image sécurisé en PHP : Tutoriel + Code complet

Besoin de mettre en place un upload d’image sécurisé en PHP sur votre site ? Que ce soit pour un avatar, une galerie photo ou un formulaire, il est essentiel de protéger votre serveur tout en offrant une expérience simple à l’utilisateur. Dans ce tutoriel, découvrez comment gérer un upload d’image en PHP de façon fiable, rapide et professionnelle.

  • Sécuriser l’envoi d’images sur un site PHP pour éviter les erreurs courantes et les risques liés aux fichiers malveillants.
  • Mettre en place une base fiable et professionnelle pour gérer avatars, galeries photo ou images produits en toute sérénité.
  • Améliorer les performances et la qualité de votre site grâce à une gestion propre des formats, du poids et du stockage des images.

Mettre en place un système d’upload d’image en PHP semble simple. On ajoute un formulaire, on clique sur “Envoyer”, et l’affaire est réglée. Pourtant, dans la réalité, c’est souvent l’un des points les plus sensibles d’un site web. Une image mal contrôlée peut remplir votre serveur, casser votre mise en page ou, pire, ouvrir une faille de sécurité. Mais avec de bonnes habitudes, vous pouvez créer un système fiable, propre et rassurant.

Dans ce tutoriel complet, vous allez apprendre à gérer l’upload d’image sécurisé en PHP, même si vous débutez. Nous allons avancer étape par étape, avec des exemples simples, concrets et faciles à réutiliser sur vos projets.

Pourquoi sécuriser l’upload d’image en PHP ?

Quand un visiteur envoie un fichier sur votre site, vous lui donnez temporairement accès à votre serveur. Dit comme ça, ça fait tout de suite plus sérieux.

Un utilisateur honnête enverra une photo de profil ou une image produit. Mais une personne mal intentionnée pourrait tenter :

  • d’envoyer un faux fichier image contenant du code dangereux,
  • de téléverser un fichier énorme pour saturer l’espace disque,
  • d’utiliser un nom de fichier piégé,
  • de remplacer un fichier existant,
  • d’envoyer des centaines de fichiers automatiquement.

C’est pour cela qu’un upload d’image en PHP ne doit jamais se limiter à move_uploaded_file() sans vérification.

Comment fonctionne un upload de fichier en PHP ?

Quand un utilisateur choisit une image dans un formulaire HTML, le navigateur l’envoie au serveur. PHP la place alors dans un dossier temporaire et remplit la variable superglobale $_FILES.

Voici les informations principales :

$_FILES['image']['name'];      // Nom original
$_FILES['image']['type'];      // Type MIME annoncé
$_FILES['image']['tmp_name'];  // Fichier temporaire
$_FILES['image']['error'];     // Code erreur
$_FILES['image']['size'];      // Taille en octets

Vous allez donc récupérer ce fichier temporaire, effectuer vos contrôles, puis le déplacer dans le bon dossier.

Créer le formulaire HTML

Commençons proprement.

<form action="upload.php" method="post" enctype="multipart/form-data">
    <label for="image">Choisissez une image :</label>
    <input type="file" name="image" id="image" required>
    
    <button type="submit">Envoyer</button>
</form>

Pourquoi enctype="multipart/form-data" ?

Sans lui, aucun fichier ne sera transmis. C’est l’oubli classique du débutant. Le genre d’erreur qui fait perdre 30 minutes… avant de soupirer très fort.

Premier script PHP d’upload

Créez maintenant le fichier upload.php sur lequel le formulaire redirige :

<?php

if(isset($_FILES['image'])) {
    echo "Fichier reçu.";
}

Si ce message s’affiche après envoi, tout fonctionne.

Étape 1 : vérifier les erreurs d’envoi

PHP attribue un code erreur. Il faut toujours le contrôler.

<?php

if ($_FILES['image']['error'] !== 0) {
    die("Erreur lors de l'envoi du fichier.");
}

Quelques erreurs possibles :

  • fichier trop volumineux,
  • envoi interrompu,
  • aucun fichier envoyé,
  • problème serveur.

Ne jamais continuer si une erreur existe.

Étape 2 : limiter la taille du fichier

Une image de 30 Mo pour un avatar ? Non merci.

$tailleMax = 2 * 1024 * 1024; // 2 Mo

if ($_FILES['image']['size'] > $tailleMax) {
    die("Image trop lourde.");
}

Cette limite dépend de votre projet :

  • avatar : 1 à 2 Mo,
  • galerie photo : 5 Mo,
  • impression HD : davantage.

Étape 3 : vérifier le vrai type du fichier

Beaucoup de débutants vérifient uniquement l’extension .jpg. Mauvaise idée.

Un pirate peut renommer :

virus.php -> photo.jpg

Il faut donc vérifier le contenu réel du fichier.

$finfo = finfo_open(FILEINFO_MIME_TYPE);
$typeMime = finfo_file($finfo, $_FILES['image']['tmp_name']);
finfo_close($finfo);

$typesAutorises = [
    'image/jpeg',
    'image/png',
    'image/gif',
    'image/webp'
];

if (!in_array($typeMime, $typesAutorises)) {
    die("Format non autorisé.");
}
  • Voilà une vraie sécurité pour votre upload d’image en PHP.

Étape 4 : générer un nom de fichier unique

Ne gardez jamais le nom original :

monimage.png

Pourquoi ?

  • caractères spéciaux,
  • accents,
  • espaces,
  • doublons,
  • noms malveillants.

Préférez un nom généré automatiquement :

$extension = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION);

$nomFichier = uniqid('img_', true) . '.' . $extension;

Exemple :

img_680c8a7a5d8c35.12345678.jpg

Simple, propre, efficace.

Étape 5 : déplacer le fichier

Créez un dossier :

uploads/

Puis :

$dossier = 'uploads/';
$destination = $dossier . $nomFichier;

if (move_uploaded_file($_FILES['image']['tmp_name'], $destination)) {
    echo "Image envoyée avec succès.";
} else {
    echo "Erreur lors de l'enregistrement.";
}

Code complet pour un upload d’image sécurisé en PHP

Voici une base sérieuse :

<?php

if (!isset($_FILES['image'])) {
    die("Aucun fichier reçu.");
}

if ($_FILES['image']['error'] !== 0) {
    die("Erreur upload.");
}

$tailleMax = 2 * 1024 * 1024;

if ($_FILES['image']['size'] > $tailleMax) {
    die("Fichier trop volumineux.");
}

$finfo = finfo_open(FILEINFO_MIME_TYPE);
$typeMime = finfo_file($finfo, $_FILES['image']['tmp_name']);
finfo_close($finfo);

$typesAutorises = [
    'image/jpeg',
    'image/png',
    'image/webp'
];

if (!in_array($typeMime, $typesAutorises)) {
    die("Format refusé.");
}

$extension = pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION);

$nom = uniqid('img_', true) . '.' . strtolower($extension);

$destination = 'uploads/' . $nom;

if(move_uploaded_file($_FILES['image']['tmp_name'], $destination)) {
    echo "Upload réussi.";
} else {
    echo "Échec.";
}

Aller plus loin pour vérifier que c’est bien une image

Même si le type MIME semble bon, vous pouvez renforcer le contrôle.

$infos = getimagesize($_FILES['image']['tmp_name']);

if ($infos === false) {
    die("Ce fichier n'est pas une image valide.");
}

Très utile pour un upload d’image sécurisé en PHP.

Redimensionner automatiquement l’image

Un visiteur envoie une photo de 5000 pixels ? Votre page pleure déjà.

Vous pouvez redimensionner avec GD.

Formation web et informatique - Alban Guillier - Formateur

Des formations informatique pour tous !

Débutant ou curieux ? Apprenez le développement web, le référencement, le webmarketing, la bureautique, à maîtriser vos appareils Apple et bien plus encore…

Formateur indépendant, professionnel du web depuis 2006, je vous accompagne pas à pas et en cours particulier, que vous soyez débutant ou que vous souhaitiez progresser. En visio, à votre rythme, et toujours avec pédagogie.

Découvrez mes formations Qui suis-je ?

En PHP, GD (pour Graphics Draw) est une extension, ou une sorte de « boîte à outils », qui permet à votre code de créer et de modifier des images directement sur le serveur.

Sans GD, PHP ne peut manipuler que du texte ou des données. Avec GD, votre site devient capable de faire des retouches automatiques sans que vous ayez besoin d’ouvrir Photoshop.

À quoi ça sert concrètement ?

Voici quelques exemples courants de ce que l’on peut faire avec la bibliothèque GD :

  • Redimensionner des photos : Créer automatiquement une miniature (thumbnail) quand un utilisateur télécharge une grande image.
  • Ajouter des filigranes (Watermarks) : Apposer votre logo sur une image pour protéger vos droits.
  • Créer des Captchas : Générer ces images avec du texte déformé pour vérifier que l’utilisateur n’est pas un robot.
  • Générer des graphiques : Transformer des chiffres d’une base de données en diagrammes ou en courbes.

Pour faire simple : GD est le « pinceau » de PHP. Il permet à votre programme de dessiner des formes, d’écrire du texte sur des photos ou de convertir une image d’un format à un autre (par exemple, transformer un PNG en JPEG).

$image = imagecreatefromjpeg($destination);

$largeur = imagesx($image);
$hauteur = imagesy($image);

$nouvelleLargeur = 800;
$nouvelleHauteur = ($hauteur / $largeur) * 800;

$miniature = imagecreatetruecolor($nouvelleLargeur, $nouvelleHauteur);

imagecopyresampled(
    $miniature,
    $image,
    0,0,0,0,
    $nouvelleLargeur,
    $nouvelleHauteur,
    $largeur,
    $hauteur
);

imagejpeg($miniature, $destination, 85);

Résultat :

  • image plus légère,
  • chargement rapide,
  • meilleur SEO,
  • meilleur confort utilisateur.
  • Pensez à bien vérifier que l’extension GD est activé

Pour vérifier que l’extension GD est bien opérationnelle sur votre serveur, la méthode la plus simple consiste à utiliser la fonction phpinfo();.

Il vous suffit de créer un petit fichier PHP (nommé par exemple test.php) contenant uniquement la ligne 

<?php phpinfo(); ?>

Puis de l’héberger sur votre serveur et de l’ouvrir dans votre navigateur. En faisant une recherche rapide (via Ctrl+F) sur la page qui s’affiche, cherchez le terme « gd » : si un tableau apparaît avec la mention « GD Support => enabled », cela signifie que tout est prêt pour que vous puissiez manipuler vos images.

Stocker le nom en base de données

Souvent, on enregistre seulement le nom du fichier.

$image = $nom;

Puis en MySQL :

INSERT INTO users (avatar) VALUES ('img_123.jpg');

Ensuite :

<img src="uploads/img_123.jpg">

Ne stockez pas l’image dans la base sauf cas spécifique.

👉 Pour en savoir plus : Le type BLOB pour stocker une image avec MySQL

Sécuriser le dossier uploads

Un excellent réflexe consiste à empêcher l’exécution de scripts PHP dans ce dossier.

Créez un fichier .htaccess :

php_flag engine off
Options -Indexes

Ainsi :

  • pas d’exécution PHP,
  • pas de listing du dossier.

Très important sur hébergement Apache.

👉 Les 20 snippets .htaccess indispensables.

Gérer les erreurs proprement

Évitez les messages brutaux :

die("Erreur.");

Préférez :

$message = "Votre image n'a pas pu être envoyée.";

Puis affichez cela joliment dans votre interface.

L’utilisateur n’a pas besoin d’avoir l’impression que le serveur est en colère.

Les erreurs fréquentes des débutants

Garder le nom original est une mauvaise idée :

photo finale version vraie.jpg

Votre serveur mérite mieux.

  • Vérifier seulement l’extension car .jpg ne garantit rien.
  • Oublier la taille maximale car un jour, quelqu’un enverra 200 Mo…
  • Enregistrer dans un dossier public sans protection. C’est très risqué.
  • Faire confiance à l’utilisateur. Internet est rempli de gens adorables… et d’autres moins.

Bonus SEO : optimiser les images envoyées

Si votre système sert à publier des articles ou fiches produits :

  • compressez les images,
  • renommez-les intelligemment,
  • ajoutez un attribut alt,
  • convertissez en WebP si possible.

Exemple :

chaise-bois-scandinave.webp

C’est excellent pour le référencement.

Conseils professionnels

Sur un vrai projet, ajoutez aussi :

  • limite du nombre d’uploads par heure,
  • antivirus serveur,
  • suppression des anciennes images,
  • génération miniature,
  • logs des erreurs,
  • captcha si public.

Petit à petit, votre upload d’image en PHP devient robuste.


Créer un système d’upload d’image sécurisé en PHP n’est pas réservé aux experts. Avec quelques vérifications simples — taille, format, nom unique, déplacement sécurisé — vous évitez déjà la majorité des problèmes. C’est souvent ce genre de détail invisible qui distingue un site amateur d’un projet sérieux.

Le plus intéressant, c’est qu’une fois cette base maîtrisée, vous pourrez aller beaucoup plus loin : avatars, galeries photo, annonces, e-commerce, portfolios, réseaux sociaux… Derrière un simple bouton “Envoyer”, il y a en réalité une vraie brique de développement web moderne. Et maintenant, vous savez la construire proprement.

👉 De manière plus générale :