🤩TD 09 et 10 : librairie CRUD en PHP (1/2)
Introduction
Dans ces séances consacrées au CRUD (Create Read Update Delete), on va créer une librairie de fonctions PHP. Ces fonctions vont nous permettre d'effectuer les opérations sur les données de la base de données. La librairie de fonctions sera à insérer dans toutes les pages de notre projet SAE203 à l'aide de l'instruction
require
.Pour se connecter à la base de données, on va utiliser le constructeur de la classe PDO, la fonction
PDO()
qui prend trois paramètres : une chaîne de caractères contenant les données de connexion (adresse IP de l'hôte, port, nom de la (data)base et charset utilisé), le login et le mot de passe utilisateur.Remarque sur la sécurité :
Tous les fichiers que nous allons créer seront situés dans un sous-dossier de votre site nommé admin/
. Ce dossier sera protégé par un fichier .htaccess
dans lequel on demandera un login et un mot de passe pour accéder à cette partie privée de votre site. En effet, lorsque votre site sera en ligne, seul un administrateur du site doit avoir le droit de modifier les données de vos tables. Cette partie "sécurité" sera traitée dans une autre séance de la SAE203.
Remarque sur le dossier des images :
Toutes les images des albums seront dans la suite de cete séance dans un dossier "images/uploads/" dans notre dossier de base de la SAE203. Ce dossier devra, lorsqu'il sera mis en ligne, pouvoir enregistrer les images téléchargées par les utilisateurs. Il faut donc mettre les DROITS D'ÉCRITURE sur ce dossier sur votre VPS et dans votre dossier de travail (si vous êtes en local sous WAMP/MAMP/LAMP). ATTENTION, les droits d'écriture sont à mettre sur le dossier "uploads" seulement, pas sur le dossier "images", ce qui rendrait modifiables TOUTES les images de votre site. Ici, on ne souhaite que pouvoir écrire les images des albums.
Remarque sur le rendu final :
Dans ces deux séances, nous ne traiterons QUE la table 1 de votre SAE203, ce sera à VOUS de FAIRE la même chose pour la gestion de la table 2 dans le rendu final ! Votre code écrit PHP pour la gestion de la table 2 sera aussi évalué dans la note finale !
1. Création de secretxyz123.inc.php
:
Afin de cacher les informations login et mot de passe dans votre code PHP, on va les mettre dans un fichier spécial qui va définir des chaînes à remplacer par d'autres grâce à la fonction
define()
.Dans le dossier principal de votre SAE203, créez un fichier
secretxyz123.inc.php
.Dans ce fichier, ajoutez les définitions de votre login et de votre mot de passe utilisateur pour la connexion à votre base de données MySQL :
<?php
// FICHIER DE DÉFINITION de chaînes de remplacement
// Mettez VOTRE LOGIN ci-dessous (2ème paramètre de define)
define('LUTILISATEUR', 'mmijlandre');
// Mettez VOTRE MOT DE PASSE ci-dessous (2ème paramètre de define)
define('LEMOTDEPASSE', 'toto@1234#');
2. Création de la librairie lib_crud.inc.php
:
Dans le dossier principal de votre SAE203, créez un fichier
lib_crud.inc.php
.Dans ce fichier, ajoutez les fonctions de connexion et de déconnexion à la base de données MySQL :
<?php
// LIBRAIRIE "lib_crud.inc.php"
// 2022 - BUT MMI - IUT Troyes - URCA
// JL
// insertion des dépendances
require 'secretxyz123.inc.php';
// connexion à la base de données
function connexionBD()
{
// on initialise la variable de connexion à null
$mabd = null;
try {
// on essaie de se connecter
// le port et le dbname ci-dessous sont À ADAPTER à vos données
$mabd = new PDO('mysql:host=127.0.0.1;port=3306;
dbname=mmijlandre;charset=UTF8;',
LUTILISATEUR, LEMOTDEPASSE);
// on passe le codage en utf-8
$mabd->query('SET NAMES utf8;');
} catch (PDOException $e) {
// s'il y a une erreur, on l'affiche
echo '<p>Erreur : ' . $e->getMessage() . '</p>';
die();
}
// on retourne la variable de connexion
return $mabd;
}
// déconnexion de la base de données
function deconnexionBD(&$mabd) {
// on se déconnexte en mettant la variable de connexion à null
$mabd=null;
}
3. Test de la librairie lib_crud.inc.php
:
Afin de tester le fonctionnement de la librairie
lib_crud.inc.php
, modifiez votre code de la pagelisting.php
pour charger la librairie de fonctions et remplacez votre code de connexion et de déconnexion par les fonctions fourniesconnexionBD()
etdeconnexionBD()
.Puis, placez votre code qui réalise l'affichage dans une fonction
afficherCatalogue($mabd)
danslib_crud.inc.php
.Le début du code de
afficherCatalogue($mabd)
devrait ressembler à ceci :
// affichage du catalogue des albums
function afficherCatalogue($mabd) {
$req = "SELECT * FROM bandes_dessinees
INNER JOIN auteurs
ON bandes_dessinees._auteur_id = auteurs.auteur_id";
try {
$resultat = $mabd->query($req);
} catch (PDOException $e) {
// s'il y a une erreur, on l'affiche
echo '<p>Erreur : ' . $e->getMessage() . '</p>';
die();
}
// ICI VOTRE CODE POUR AFFICHER LES ALBUMS
// ...
// ...
}
Votre code simplifié dans
listing.php
devrait ressembler à quelque chose comme ça (c'est beaucoup plus court, non ?) :
...
<body style="font-family:sans-serif;">
<a href="index.php">Accueil</a> | <a href="listing.php">Catalogue</a> | <a href="admin/admin.php">Admin.</a>
<hr />
<h1>Nos albums</h1>
<hr />
<?php
require 'lib_crud.inc.php';
$co=connexionBD();
afficherCatalogue($co);
deconnexionBD($co);
?>
</body>
</html>
Le résultat affiché devrait ressembler à quelque chose comme ça (évidemment, cet affichage dépend de vos données et de vos styles CSS) :

4. Création de la page admin.php :
Dans votre dossier de travail "sae203", vous devez créer un dossier "admin" (qui sera protégé par un .htaccess plus tard).
Dans le menu général, le lien "Admin." va pointer vers "admin/admin.php" (la page d'administration des données de votre site).
Dans le dossier
admin
, on va créer un fichieradmin.php
dans lequel on va mettre le code :
<!DOCTYPE html>
<html>
<head>
<title>SAE203</title>
</head>
<body style="font-family:sans-serif;">
<a href="../index.php">Accueil</a>
<hr />
<h1>Gestion des données</h1>
<ul>
<li>Gestion des <a href="table1_gestion.php">albums</a></li>
<li>Gestion des <a href="table2_gestion.php">auteurs</a></li>
</ul>
</body>
</html>
Dans le dossier
admin
, on va créer un fichiertable1_gestion.php
dans lequel on va mettre le code :
<!DOCTYPE html>
<html>
<head>
<title>SAE203</title>
</head>
<body>
<a href="../index.php">Accueil</a>
<hr />
<h1>Gestion des données</h1>
<p><a href="table1_new_form.php">Ajouter une bande dessinée</a></p>
<?php
require '../lib_crud.inc.php';
$co=connexionBD();
afficherListe($co);
deconnexionBD($co);
?>
</body>
</html>
Il faut donc créer une fonction
afficherListe()
danslib_crud.inc.php
qui va afficher une table HTML contenant les informations sur les bandes dessinées :
...
// affichage de la liste des albums pour la gestion
function afficherListe($mabd) {
$req = "SELECT * FROM bandes_dessinees
INNER JOIN auteurs
ON bandes_dessinees._auteur_id = auteurs.auteur_id";
try {
$resultat = $mabd->query($req);
} catch (PDOException $e) {
// s'il y a une erreur, on l'affiche
echo '<p>Erreur : ' . $e->getMessage() . '</p>';
die();
}
echo '<table>'."\n";
echo '<thead><tr><th>Photo</th><th>Titre</th><th>Prix (€)</th><th>Pages</th><th>Auteur</th><th>Modifier</th><th>Supprimer</th></tr></thead>'."\n";
echo '<tbody>'."\n";
foreach ($resultat as $value) {
echo '<tr>'."\n";
echo '<td><img class="photo" src="../images/uploads/'.$value['bd_photo'].'" alt="image_'.$value['bd_id'].'" /></td>'."\n";
echo '<td>'.$value['bd_titre'].'</td>'."\n";
echo '<td>'.$value['bd_prix'].'</td>'."\n";
echo '<td>'.$value['bd_nb_pages'].'</td>'."\n";
echo '<td>'.$value['auteur_prenom'].' '.$value['auteur_nom'].'</td>'."\n";
echo '<td><a href="table1_update_form.php?num='.$value['???'].'">Modifier</a></td>'."\n";
echo '<td><a href="table1_delete.php?num='.$value['???'].'">Supprimer</a></td>'."\n";
echo '</tr>'."\n";
}
echo '</tbody>'."\n";
echo '</table>'."\n";
}
...
Attention, dans le code ci-dessus,
...
n'est pas une instruction PHP valide, c'est juste pour indiquer que ce code est dans . De plus, il faut changer les???
pour afficher le numéro de la bande dessinée afin de le passer à la page de modification et à la page de suppression.Testez votre code, la page obtenue decrait ressembler à ceci (selon votre CSS évidemment) :

5. Ajout d'une bande dessinée (liste des auteurs) :
Pour ajouter un bande dessinée à notre catalogue (pour insérer les données dans MySQL), on va créer un fichier
table1_new_form.php
dans lequel on va insérer le code suivant :
<!DOCTYPE html>
<html>
<head>
<title>SAE203</title>
</head>
<body style="font-family:sans-serif;">
<a href="../index.php">Accueil</a> | <a href="admin.php">Gestion</a>
<hr />
<h1>Ajouter une bande dessinée</h1>
<hr />
<form action="table1_new_valide.php" method="POST" enctype="multipart/form-data">
Titre : <input type="text" name="titre" required /><br />
Année : <input type="number" name="annee" min="-5000" max="3000" required /><br />
Nb pages : <input type="number" name="pages" required /><br />
Prix : <input type="number" name="prix" min="0.00" max="10000.00" step="0.01" required /><br />
Résumé : <textarea name="resume" required></textarea><br />
Photo : <input type="file" name="photo" required /><br />
Auteur : <select name="auteur" required>
<?php
require '../lib_crud.inc.php';
$co=connexionBD();
afficherAuteursOptions($co);
deconnexionBD($co);
?>
</select><br />
<input type="submit" value="Ajouter" />
</form>
</body>
</html>
Attention, le formulaire est OBLIGATOIREMENT en méthode POST car on va passer une image à notre site, donc on va utiliser un champ de type
file
. On précise de plus l'encodage de notre image :multipart/form-data
.Pour afficher la liste des auteurs, il faut ajouter dans notre librairie
lib_crud.inc.php
le code qui va permettre de générer la liste des prénoms et noms des auteurs sous la forme de balises<option>
dans une balise HTML<select>
.Le code de la fonction
afficherAuteursOptions($co)
doit ressembler à ceci :
// afficher les auteurs (prénom et nom) dans des champs "option"
function afficherAuteursOptions($mabd) {
// on sélectionne tous les auteurs de la table auteurs
$req = "SELECT * FROM auteurs";
try {
$resultat = $mabd->query($req);
} catch (PDOException $e) {
// s'il y a une erreur, on l'affiche
echo '<p>Erreur : ' . $e->getMessage() . '</p>';
die();
}
// pour chaque auteur, on met son id, son prénom et son nom
// dans une balise <option>
foreach ($resultat as $value) {
echo '<option value="'.???.'">'; // id de l'auteur
echo ???.' '.???; // prénom espace nom
echo '</option>'."\n";
}
}
Testez votre code, vous devriez avoir quelque chose comme ceci (la liste déroulante contient bien TOUS les prénoms et noms des auteurs) :

6. Ajout d'une bande dessinée (validation) :
On va maintenant valider les changements dans la table
bandes_dessinees
.On va créer le fichier
table1_new_valide.php
qui va récupérer les informations de la nouvelle BD (avec l'image à télécharger) et qui va insérer les informations dans la table.Le code de la page
table1_new_valide.php
est donné ici :
<!DOCTYPE html>
<html>
<head>
<title>SAE203</title>
</head>
<body style="font-family:sans-serif;">
<a href="../index.php">Accueil</a> | <a href="admin.php">Gestion</a>
<hr />
<h1>Ajouter une bande dessinée</h1>
<hr />
<?php
require '../lib_crud.inc.php';
$titre=$_POST['titre'];
$prix=$_POST['prix'];
$annee=$_POST['annee'];
$nbPages=$_POST['pages'];
$resume=trim($_POST['resume']);
$auteur=$_POST['auteur'];
var_dump($_POST);
var_dump($_FILES);
$imageType=$_FILES["photo"]["type"];
if ( ($imageType != "image/png") &&
($imageType != "image/jpg") &&
($imageType != "image/jpeg") ) {
echo '<p>Désolé, le type d\'image n\'est pas reconnu !';
echo 'Seuls les formats PNG et JPEG sont autorisés.</p>'."\n";
die();
}
$nouvelleImage = date("Y_m_d_H_i_s")."---".$_FILES["photo"]["name"];
if(is_uploaded_file($_FILES["photo"]["tmp_name"])) {
if(!move_uploaded_file($_FILES["photo"]["tmp_name"],
"../images/uploads/".$nouvelleImage)) {
echo '<p>Problème avec la sauvegarde de l\'image, désolé...</p>'."\n";
die();
}
} else {
echo '<p>Problème : image non chargée...</p>'."\n";
die();
}
$co=connexionBD();
ajouterBD($co, $titre, $annee, $prix,
$nouvelleImage, $nbPages, $resume, $auteur);
deconnexionBD($co);
?>
</body>
</html>
Dans ce code, on récupère les informations passées par le formulaire de la page précédente, on vérifie ensuite le type de l'image, on la récupère sur le serveur (VPS ou local) dans le dossier "images/uploads/" (en la renommant en ajoutant la date) et on appelle la fonction
ajouterBD()
en lui passant les informations nécessaires pour insérer les données dans la tablebandes_dessinees
.Le code (incomplet) de la fonction
ajouterBD()
à mettre danslib_crud.inc.php
est :
// fonction d'ajout d'une BD dans la table bande_dessinees
function ajouterBD($mabd, $titre, $annee, $prix, $nouvelleImage, $nbPages, $resume, $auteur)
{
$req = 'INSERT INTO bandes_dessinees (bd_titre, bd_annee, bd_prix, bd_photo, bd_nb_pages, bd_resume, _auteur_id) VALUES (???)';
echo '<p>' . $req . '</p>' . "\n";
try {
$resultat = $mabd->query($req);
} catch (PDOException $e) {
// s'il y a une erreur, on l'affiche
echo '<p>Erreur : ' . $e->getMessage() . '</p>';
die();
}
if ($resultat->rowCount() == 1) {
echo '<p>La bande dessinée ' . $titre . ' a été ajoutée au catalogue.</p>' . "\n";
} else {
echo '<p>Erreur lors de l\'ajout.</p>' . "\n";
die();
}
}
Il faut remplacer les
???
par le code PHP qui va générer le "INSERT INTO" de façon correcte.Testez votre code jusqu'à avoir la nouvelle bande dessinée qui apparait dans la liste des albums.



7. Un peu de nettoyage :
Quand tout fonctionne, vous pouvez "nettoyer" votre code en enlevant TOUS les affichages qui ne servent plus : les requêtes, les
print_r()
, lesvar_dump()
... Pour cela, mettez-les en commentaires dans tous les fichiers concernés :
//echo '<p>'.$req.'</p>."\n";
//var_dump($_POST);
//var_dump($_FILES);
Dernière mise à jour