TD10 - PHP/MySQL : Upload d’images
Objectif
Dans ce TD, nous allons voir comment permettre aux utilisateurs de votre site de joindre une photo JPG lorsqu’il remplissent un formulaire.
Nous prenons un exemple simple de fournir un nom de paysage, et joindre une photo. Les noms des paysages seront enregistré dans une table
paysage
(avec les champsid
,nom
, etdatecreation
), et les images fournies par les utilisateurs seront stockées dans un dossierimages_upload
.Les noms des fichiers image seront construits à partir de l’identifiant
id
de la table MySQL, afin de pouvoir les associer au bon enregistrement de la table MySQLpaysage
. Par exemple, quand l’identifiantid
est 1, le fichier s’appellerapaysage-1.jpg
, dans le dossierimages_upload
.Pour connaître l’identifiant d’un nouvel enregistrement inséré dans une tale de la base de données, qui a été déterminé grâce à l’option AUTO_INCREMENT, nous allons utiliser une fonction PHP
$pdo->lastInsertId();
.
Téléverser un fichier (upload)
Exercice 10.1 Environnement de travail
- Aujourd’hui, nous travaillons dans le dossier
td10
. Copiez votre fichierconnexion_base.php
dans ce dossiertd10
.
Exercice 10.2 phpinfo
- Créer un fichier
phpinfo.php
qui contient uniquement la ligne suivante (même pas les en-têtes HTML).
<?php phpinfo(); ?>
- Ouvrir ce fichier avec un navigateur. Regardez surtout les variables
upload_max_filesize
, etDOCUMENT_ROOT
.
Exercice 10.3 Création d’une table dans la base de données
Dans cet exercice, on créera une table paysage
qui permet de définir un nom pour le paysage, et la date et l’heure de l’ajout.
Bien sûr, dans un plus grand projet, vous pourriez ajouter des autres informations, comme une description détaillée, le pays où se trouve le paysage (p.ex. via un clé étrangère vers une table pays
), les coordonnées GPS exacts où se trouve le paysage, etc. Mais ce n’est pas le sujet de cet exercice pour l’instant
- Créez la structure de cette table comme suit.
Table paysage
id | nom | datecreation |
---|---|---|
INT | TEXT | DATETIME |
N’oubliez pas de déclarer l’identifiant id
en clé primaire et A_I (auto increment), comme d’habitude.
- Créer quelques enregistrement dans cette table avec phpmyadmin, et regardez bien la requête INSERT qui est générée.
Exercice 10.4 Formulaire pour un noveau paysage
Dans cet exercice, nous créons un formulaire pour ajouter un paysage.
- Avec VSCode, créez une nouvelle page
paysage-formulaire.php
. Cette page contiendra toutes les balises d’une page HTML5. Dans le corps de cette page (après<body>
), créez un titreh2
avec le texte “Ajoutez un nouveau paysage”, ainsi qu’un formulaire qui renvoie vers la page{\tt
paysage-enregistrer.phpavec la méthode
post` comme suit :
<h2>Ajoutez un nouveau paysage</h2>
<form action="paysage-enregistrer.php" enctype="multipart/form-data" method="post">
<input type="text" name="nom" /><br />
<input type="hidden" name="MAX_FILE_SIZE" value="13000000" />
<input type="file" name="fichier" /><br />
<input type="submit" />
</form>
Pour pouvoir téléverser un fichier, il faut travailler avec la méthode POST, et d’avoir l’attribut suivant dans votre formulaire :
="multipart/form-data" enctype
Exercice 10.5 Enregistrer les informations sur le paysage dans la base de données
Dans cet exercice, nous allons enregistrer les informations sur le nouveau paysage dans la table paysage
.
- Créez un fichier
paysage-enregistrer.php
avec toutes les balises d’une page HTML5. N’oubliez pas d’inclure le fichierconnexion_base.php
en tout début du fichier :
<?php require_once("connexion_base.php"); ?>
- Pour récupérer le nom du paysage depuis le formulaire, et pour insérer les données dans votre table
categorie
, vous pouvez faire comme d’habitude. Pour simplifier, je vous donne la solution. En tout début de page :
<?php
if (!empty($_POST['nom']))
{$nom = $_POST['nom'];
// exécuter une requete MySQL de type INSERT
$requete="INSERT INTO paysage (nom, datecreation) VALUES (?,NOW())";
$reponse=$pdo->prepare($requete);
$reponse->execute(array($nom));
// récupérer l'idenitifant du dernier enregistrement inséré
$message = "Votre paysage a été ajouté dans la base de données.";
// code du prochain exercice ici
}else
{$message = "Spécifiez un nom de paysage svp.";
}?>
Dans la partie
body
, affichez un paragraphe avec le message de la variable$message
.Testez votre formulaire en ajoutant un nouveau paysage, pour l’instant sans fichier image.
Après l’insertion dans la base de données, il faut récupérer l’identifiant
id
du nouvel enregistrement afin de pouvoir créer le bon nom de fichier dans le prochain exercice. Vous pouvez faire ceci en appelant la fonction suivante :
// récupérer l'idenitifant du dernier enregistrement inséré
$dernier_id = $pdo->lastInsertId();
Ajustez la variable message pour afficher également cet identifiant
$dernier_id
.Testez, et vérifiez qu’un nouvel enregistrement se crée dans votre table
paysage
de votre base de données.
Exercice 10.6 Enregistrer le fichier avec le bon nom de fichier
Dans cet exercice, nous allons enregistrer l’image du nouveau paysage dans le dossier images_upload
, et donner le bon nom du fichier pour pouvoir l’associer au bon enregistrement de la table paysage
par son identifiant id
.
Créez un dossier
images_upload
dans votre dossier de travailtd10
.Insérez le script PHP suivant (à l’endroit commentaire
// code du prochain exercice ici
).
Essayez de comprendre ce code PHP qui va rajouter le fichier dans votre dossier images_upload
, et qui lui donne un nom qu’on peut associer avec l’identifiant du paysage de la table paysage
de la base de données.
print_r($_FILES['fichier']); // Commentez cette ligne quand tout va bien
print_r($_FILES); // Commentez cette ligne quand tout va bien
print_r($_POST); // Commentez cette ligne quand tout va bien
if(!empty($_FILES['fichier']['tmp_name']))
{$size = getimagesize($_FILES['fichier']['tmp_name']);
print_r($size); // Commentez cette ligne quand tout va bien
echo "Filetype : ".$size['mime']; // Commentez cette ligne quand tout va bien
if ($size['mime'] == "image/jpeg")
{$uploaddir = $_SERVER['DOCUMENT_ROOT']."/cswd/td10/images_upload/";
$uploadfile = "paysage-".$dernier_id.".jpg";
if (move_uploaded_file($_FILES['fichier']['tmp_name'], $uploaddir.$uploadfile))
{$message = $message ." Votre image du paysage a bien été ajouté : ".$uploadfile;
}else
{$message = $message . "Problème sur le serveur : ".$uploaddir;
}
}else
{$message = $message . "Pas le bon type de fichier : ".$size['mime'];
}
}else
{ $message = $message . "Pas de fichier spécifié.";
}
Testez votre formulaire en mettant un nom de paysage, et en spécifiant un fichier JPG de votre choix.
Vérifier que le fichier est bien enregistré dans votre dossier
image_upload
, et que le nom du fichier est associé au bon enregistrement de la tablepaysage
. Attention ! Si vous travaillez dans un autre dossier quecswd/td10
, il faut adapter la ligne correspondante dans le code ci-dessus !Vous pouvez maintenant sortir les trois lignes qui affichent les tableau associatifs
$_FILES
et$_POST
.
Exercice 10.7 Afficher les paysages
Créez une page
paysages.php
avec les balises HTML5 habituelles, et qui affiche tous les noms des paysages dans une table<table>
avec des lignes<tr>
.Pour chaque élément de liste, affichez également l’image du paysage concernée.
Exercice 10.8 Transfert au serveur du CREMI
Si vous travaillez sur les ordinateurs du CREMI, vous pouvez déjà passer au prochain exercice.
Si vous ne travaillez pas directement sur les ordinateurs du CREMI, l’objectif de cet exercice est de transférer vos pages web au CREMI, en utilisant la base de données du CREMI.
Transférez votre dossier td10 au CREMI (avec Filezilla).
Transférez votre table
paysage
de la base de données au CREMI, via les interfaces web phpmyadmin. Alternativement, vous pouvez aussi créez la table dans votre base de données du CREMI, via phpmyadmin.Testez l’ajout de paysage sur votre site hébergé au CREMI.
Exercice 10.9 Description fonctionnelle
Avant le Mercredi, 2 Avril 2025, 23h59, vous devez déposer votre description fonctionnelle sur moodle. Notez qu’il suffit qu’un seul membre de votre équipe de projet dépose cette description !} C’est un document PDF de de 4 pages maximum qui doit s’appeler selon votre numéro et nom du projet, tel qu’il est sur framateam, donc p.ex. 401-prise-rdv-kine.pdf.
Notez que la partie centrale de votre projet est la base de données, qui concrétise votre idées, faites donc bien attention de bien structurer votre base de données par des tables qui sont en relation les uns par rapport aux autres !
Les détails sont expliquées ici :
https://www.labri.fr/perso/preuter/cswd2025/projet_description_fonctionnelle.pdf
Exercices optionnels
Exercice 10.10 Test sur téléphone
Comme votre site est en ligne est accessible sur Internet, vous pouvez aussi l’afficher sur votre téléphone. Soit vous saisissez l’URL de votre page sur votre téléphone, soit, vous créez un QR Code de cet URL, p.ex. en utilisant l’outil ci-dessus :
https://patrick-reuter.emi.u-bordeaux.fr/qrcode/phpqrcode/index.php
Exercice 10.11 Création de miniatures des images
Lors du téléversement d’une image par un utilisateur, il est souvent intéressant de changer la définition de l’image en terme de nombre de pixels et/ou des créer des miniatures des images, tout en gardant le rapport largeur/hauteur (aspect ratio). Si vous voulez imposer un certain rapport largeur/hauteur, il faut aussi découper l’image pour éviter “d’étirer” l’image, ou alors vous fixez une largeur, et vous calulez la hauteur en fonction du aspect ratio. La bibliothèque “gd” de PHP, qui est souvent préinstallé, propose des fonctions très intéressantes pour ce faire, par exemple imagecopyresized (https://www.php.net/manual/fr/function.imagecopyresized.php) et imagecopyresampled (https://www.php.net/manual/fr/function.imagecopyresampled.php).
N’oubliez pas de rendre votre description fonctionnelle sur moodle avant mercredi 2 avril prochain, 23h59. Cela vous aidera à définir et concrétiser votre projet.
Comme d’habitude, les exercices sont à rendre sur moodle jusqu’à mercredi 2 avril prochain, 23h59.