🐘 PHP + Base de Données

Avec PDO (PHP Data Object)

Tout expliqué pas à pas

Formation DWWM - 2025-2026

Au programme 📋

On va apprendre TOUT depuis zéro :

  • 🎯 C'est quoi une base de données et PHP qui communiquent ?
  • 🔌 Se connecter : comment PHP "parle" à MySQL
  • 📡 Récupérer des données : afficher des infos
  • 💀 Le DANGER : l'injection SQL (expliqué simplement)
  • 🛡️ Se protéger : les requêtes préparées
  • ✏️ Modifier des données : ajouter, modifier, supprimer
  • 🏗️ Organiser son code : faire du code propre
💡 Pas de panique ! Tout sera expliqué avec des exemples du quotidien

🎓 Partie 0

Les bases (pour bien comprendre)

On commence par le commencement

C'est quoi PHP + Base de données ? 🤔

📚 Analogie de la bibliothèque :

PHP = Le bibliothécaire
Il cherche des livres, les range, les modifie...

Base de données (MySQL) = Les étagères avec les livres
Tous les livres sont rangés, organisés, stockés

PDO = La langue que le bibliothécaire utilise pour parler aux étagères
Sans PDO, le bibliothécaire ne peut pas communiquer !
┌──────────────┐ │ Utilisateur │ <- Clique sur "Voir mes commandes" └──────┬───────┘ │ ▼ ┌──────────────┐ │ PHP │ <- "Je dois récupérer les commandes" │ (le script) │ └──────┬───────┘ │ PDO (communication) ▼ ┌──────────────┐ │ MySQL │ <- Trouve les commandes et les renvoie │ (stockage) │ └──────────────┘

Exemple concret : Site e-commerce 🛒

Ce qui est dans la base de données :

  • 📦 Les produits (nom, prix, photo, stock...)
  • 👤 Les clients (nom, email, adresse...)
  • 🧾 Les commandes (qui a acheté quoi, quand...)

Ce que fait PHP :

  • Affiche les produits sur la page d'accueil
  • Cherche un produit quand on tape dans la barre de recherche
  • Enregistre une commande quand on clique "Acheter"
  • Affiche l'historique des commandes du client
💡 En résumé :
MySQL = stocke les données
PHP = affiche et manipule les données
PDO = fait le lien entre les deux

Pourquoi on utilise PDO ? 🎯

🏪 Analogie du traducteur universel :

Vous voulez acheter dans des magasins de différents pays :
- 🇫🇷 Magasin français (MySQL)
- 🇬🇧 Magasin anglais (PostgreSQL)
- 🇯🇵 Magasin japonais (SQLite)

PDO = Votre traducteur qui parle TOUTES les langues !
Vous parlez français → PDO traduit dans la bonne langue
✅ Avantage concret :
Votre entreprise utilise MySQL. Dans 2 ans, elle passe à PostgreSQL.
Avec PDO : Changer 2-3 lignes de config
Sans PDO : Réécrire TOUT le code !

🔌 Partie 1

Se connecter à la base de données

Le premier contact

Qu'est-ce qu'une connexion ? 🤝

📞 Analogie du coup de téléphone :

Se connecter = Appeler MySQL au téléphone
MySQL répond : "Allô oui ?"
PHP dit : "C'est moi, PHP. Voici mon mot de passe"
MySQL : "OK, je te reconnais. Tu peux me parler maintenant."

Une fois connecté, PHP peut poser des questions (requêtes SQL)
Dialogue de connexion : PHP : "Bonjour MySQL, je voudrais me connecter" (new PDO(...)) MySQL : "Qui es-tu ? Quel est ton mot de passe ?" PHP : "Je suis 'root' et mon mot de passe est ''" MySQL : "OK je te connais. A quelle base de données ?" PHP : "A la base 'ma_base'" MySQL : "D'accord, connexion etablie ! Tu peux me parler." PHP : Peut maintenant faire des requetes SQL

Code de connexion - Version simple 🔧

<?php
// Informations de connexion (comme un trousseau de cles)
$host = 'localhost';       // Ou est MySQL ? (ici, sur cet ordinateur)
$dbname = 'ma_base';       // Quelle base de donnees ?
$username = 'root';        // Qui se connecte ?
$password = '';            // Mot de passe (souvent vide en local)

// Creer la connexion
$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);

echo "Connecte !";  // Si ca affiche, ca a marche !
?>
📝 Explication ligne par ligne :
$host = 'localhost' → MySQL est sur CET ordinateur
$dbname = 'ma_base' → On veut accéder à la base "ma_base"
$username = 'root' → On se connecte en tant que "root" (admin)
$password = '' → Pas de mot de passe en local (chaîne vide)
new PDO(...) → Crée la connexion, stockée dans $pdo

Décomposition du DSN 🔍

$pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
               │         │      │           │           │           │
               │         │      │           │           │           Mot de passe
               │         │      │           │           Nom utilisateur
               │         │      │           Nom de la base
               │         │      Serveur (localhost = cet ordi)
               │         Type de BDD (mysql, pgsql, sqlite...)
               Objet PDO (connexion etablie)
DSN = Data Source Name (Nom de la source de donnees) C'est comme une adresse complete : "mysql:host=localhost;dbname=ma_base" │ │ │ │ │ Appartement (quelle base ?) │ Rue (quel serveur ?) Ville (quel type de BDD ?)
💡 Pourquoi "localhost" ?
En développement, MySQL est sur le même ordi que PHP.
"localhost" = "cet ordinateur"
En production, ça sera une IP ou un nom de serveur

Et si ça ne marche pas ? 🚨

<?php
try {
    // Essayer de se connecter
    $pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
    echo "Connexion reussie !";
    
} catch (PDOException $e) {
    // Si ca echoue, on arrive ici
    echo "Erreur : " . $e->getMessage();
    die();  // Arreter le script
}
?>
📝 Comment ça marche :
try { ... } → "Essaye de faire ça"
catch (PDOException $e) { ... } → "Si ça plante, fais ça"
$e->getMessage() → Le message d'erreur de MySQL
die() → Arrête tout (on peut pas continuer sans BDD)

Erreurs courantes et solutions 🔧

Erreur Signification Solution
Access denied for user 'root'@'localhost' Mauvais user ou password Vérifier username/password
Unknown database 'ma_base' La base n'existe pas Créer la base dans phpMyAdmin
Connection refused MySQL n'est pas démarré Démarrer MySQL (XAMPP/WAMP)
could not find driver Extension PDO pas activée Activer pdo_mysql dans php.ini
⚠️ Si vous voyez une erreur : Lisez-la ! Elle dit ce qui ne va pas.

Configuration recommandée ⚙️

<?php
$host = 'localhost';
$dbname = 'ma_base';
$username = 'root';
$password = '';

// DSN (Data Source Name)
$dsn = "mysql:host=$host;dbname=$dbname;charset=utf8mb4";
        //                                  ^
        //                                  IMPORTANT pour les accents et emojis

// Options de configuration
$options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,  // Afficher les erreurs
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,  // Format tableau associatif
    PDO::ATTR_EMULATE_PREPARES => false,  // Vraies requetes preparees
];

try {
    $pdo = new PDO($dsn, $username, $password, $options);
    echo "Connexion OK !";
} catch (PDOException $e) {
    die("Erreur : " . $e->getMessage());
}
?>
💡 charset=utf8mb4 : Permet d'utiliser les accents (éèà) ET les émojis 😊
Sans ça, "café" devient "caf?" dans la BDD !

📖 Partie 2

Votre première requête

Récupérer des données

C'est quoi une requête ? 💭

📚 Retour à la bibliothèque :

Vous demandez au bibliothécaire :
"Donne-moi tous les livres de science-fiction"

Le bibliothécaire va chercher et vous les ramène.

En base de données :
PHP demande : "Donne-moi tous les clients"
MySQL cherche et renvoie la liste
PHP -> MySQL : "SELECT * FROM client" (Donne-moi tout ce qu'il y a dans la table client) MySQL cherche dans la table... MySQL -> PHP : Voici 25 clients PHP peut maintenant afficher ces 25 clients

SELECT - Récupérer des données 📊

On a cette table "client" dans MySQL :

id nom email
1 Dupont dupont@email.com
2 Martin martin@email.com
3 Durand durand@email.com

Code PHP pour afficher les clients :

<?php
// 1. Connexion (deja faite avant)
// $pdo est deja connecte

// 2. Preparer la requete SQL
$sql = "SELECT * FROM client";
//      ^      ^       ^
//      |      |       Nom de la table
//      |      * = tout (id, nom, email...)
//      Commande SQL (recuperer)

// 3. Executer la requete
$stmt = $pdo->query($sql);
//      ^         ^
//      |         Envoie la requete a MySQL
//      Resultat (objet PDOStatement)

// 4. Parcourir les resultats
while ($client = $stmt->fetch()) {
    // $client = un tableau avec les donnees d'UN client
    echo $client['nom'] . " - " . $client['email'] . "<br>";
}
?>

Décomposition du code 🔍

Étape 1 : La requête SQL
SELECT * FROM client
  ^    ^   ^    ^
  |    |   |    Nom de la table
  |    |   "DEPUIS" (depuis quelle table ?)
  |    * = "tout" (toutes les colonnes)
  "SELECTIONNE" (recupere des donnees)
Étape 2 : Exécuter
$stmt = $pdo->query($sql);
  ^       ^         ^
  |       |         La requete SQL
  |       Methode pour executer
  Resultat (contient les clients)
Étape 3 : Récupérer
$client = $stmt->fetch();
  ^         ^         ^
  |         |         Recupere UNE ligne
  |         Le resultat de la requete
  Tableau avec les donnees d'un client

// Exemple de ce qui est dans $client :
$client = [
    'id' => 1,
    'nom' => 'Dupont',
    'email' => 'dupont@email.com'
]

fetch() vs fetchAll() 🆚

🍪 Analogie des cookies :

Vous avez un paquet de cookies devant vous.

fetch() = Prendre UN cookie à la fois
Vous prenez le premier → vous le mangez
Vous prenez le deuxième → vous le mangez
etc.

fetchAll() = Prendre TOUS les cookies d'un coup
Vous videz le paquet dans un bol
fetch() - Un par un :
while ($client = $stmt->fetch()) {
    echo $client['nom'] . "<br>";
}
// Affiche :
// Dupont
// Martin
// Durand
fetchAll() - Tous d'un coup :
$clients = $stmt->fetchAll();
// $clients est un GRAND tableau contenant TOUS les clients

foreach ($clients as $client) {
    echo $client['nom'] . "<br>";
}
// Meme resultat mais tout est en memoire d'un coup

Quand utiliser quoi ? 🤔

Méthode Quand l'utiliser Avantage
fetch() Beaucoup de résultats (1000+ lignes) Économise la mémoire
fetchAll() Peu de résultats (< 1000 lignes) Plus simple, tout d'un coup
💡 Pour débuter : Utilisez fetchAll(), c'est plus simple !
Plus tard, utilisez fetch() pour de GRANDES tables.

💀 Partie 3

Le DANGER : Injection SQL

Expliqué très simplement

C'est quoi une injection SQL ? 🤔

🎭 Analogie du ventriloque :

Imaginez un robot qui répète EXACTEMENT ce que vous dites.
Vous dites : "Dis bonjour" → Robot : "Bonjour"
Vous dites : "Dis au revoir" → Robot : "Au revoir"

Mais un méchant dit : "Dis 'au revoir' ET casse tout"
Robot : "Au revoir" + CASSE TOUT 💥

L'injection SQL = Faire faire au robot (MySQL) ce qu'on ne voulait pas !

Exemple concret - Formulaire de connexion 🔐

Formulaire normal :

┌─────────────────────────────┐ │ CONNEXION │ │ │ │ Email : dupont@email.com │ │ Password : monmotdepasse │ │ │ │ [ SE CONNECTER ] │ └─────────────────────────────┘

Code PHP (DANGEREUX) :

<?php
// Recuperer ce que l'utilisateur a tape
$email = $_POST['email'];
$password = $_POST['password'];

// Construire la requete SQL
$sql = "SELECT * FROM user WHERE email = '$email' AND password = '$password'";
                                                ^                    ^
                                               On met les variables DIRECTEMENT dans le SQL

// Executer
$stmt = $pdo->query($sql);
$user = $stmt->fetch();

if ($user) {
    echo "Connecte !";
} else {
    echo "Erreur";
}
?>

L'attaque en action 💣

Un utilisateur normal tape :

Email : dupont@email.com Password : monmotdepasse SQL genere : SELECT * FROM user WHERE email = 'dupont@email.com' AND password = 'monmotdepasse' ✅ Normal, ca marche comme prevu

Un PIRATE tape :

Email : admin@site.com Password : ' OR '1'='1 SQL genere (DANGEREUX !) : SELECT * FROM user WHERE email = 'admin@site.com' AND password = '' OR '1'='1' ^ TOUJOURS VRAI ! 💀 Le pirate est CONNECTE sans mot de passe !

Pourquoi ça marche ? 🧐

Analysons le SQL genere : SELECT * FROM user WHERE email = 'admin@site.com' AND password = '' OR '1'='1' Decomposition : 1. email = 'admin@site.com' -> Peut-etre VRAI (si cet email existe) 2. password = '' -> FAUX (pas le bon mot de passe) 3. '1'='1' -> TOUJOURS VRAI ! Evaluation complete : (email OK AND password FAUX) OR VRAI = FAUX OR VRAI = VRAI Resultat : CONNEXION REUSSIE sans bon mot de passe !
💀 Le problème :
Le pirate a injecté du CODE SQL (' OR '1'='1) dans le mot de passe !
PHP a construit une requête avec ce code et MySQL l'a exécutée !

Autre attaque - Voler des données 🕵️

Site de vente avec recherche de produits :

// Code DANGEREUX
$recherche = $_GET['q'];  // Ce que l'utilisateur tape dans la recherche
$sql = "SELECT * FROM produit WHERE nom LIKE '%$recherche%'";
$stmt = $pdo->query($sql);

Recherche normale :

URL : produit.php?q=telephone SQL : SELECT * FROM produit WHERE nom LIKE '%telephone%' ✅ Affiche tous les telephones

Attaque :

URL : produit.php?q=phone' UNION SELECT id, email, password, NULL FROM user -- SQL : SELECT * FROM produit WHERE nom LIKE '%phone' UNION SELECT id, email, password, NULL FROM user -- %' 💀 Affiche TOUS les emails et mots de passe !

Comment se protéger ? 🛡️

✅ LA SOLUTION : Requêtes préparées

Principe : SÉPARER le code SQL des données

Au lieu de mélanger tout ensemble, on dit à MySQL :
1️⃣ "Voici la structure de ma requête" (avec des marqueurs)
2️⃣ "Voici les données" (envoyées séparément)

MySQL sait que les données = TEXTE, pas CODE
📝 Analogie du formulaire à trous :

Requête préparée = Formulaire administratif avec des cases vides
"Nom : ________"
"Prénom : ________"

Vous remplissez SEULEMENT les cases vides.
Impossible de modifier la structure du formulaire !

🛡️ Partie 4

Requêtes Préparées

La protection expliquée simplement

Requête préparée - Le concept 🎯

AVANT (DANGEREUX) - Tout melange : PHP construit : "SELECT * FROM user WHERE email = '$email'" ^ Variable dedans ! MySQL recoit : SELECT * FROM user WHERE email = 'pirate' OR '1'='1' MySQL execute : Tout, meme le code malveillant ! AVEC REQUETE PREPAREE (SECURISE) - Separe : 1. PHP envoie la STRUCTURE : "SELECT * FROM user WHERE email = ?" ^ Marqueur (trou) 2. PHP envoie les DONNEES : "pirate' OR '1'='1" 3. MySQL recoit : Structure : SELECT * FROM user WHERE email = ? Donnee : "pirate' OR '1'='1" <- Traite comme TEXTE MySQL cherche un email qui s'appelle EXACTEMENT "pirate' OR '1'='1" -> Aucun resultat ! Attaque bloquee !

Code avec requête préparée ✅

<?php
// Recuperer les donnees utilisateur
$email = $_POST['email'];
$password = $_POST['password'];

// ETAPE 1 : Preparer la requete (structure avec marqueurs ?)
$sql = "SELECT * FROM user WHERE email = ? AND password = ?";
                                             ^                ^
                                             Marqueurs (trous)

$stmt = $pdo->prepare($sql);
//           ^
//           "prepare" au lieu de "query" !

// ETAPE 2 : Executer avec les donnees
$stmt->execute([$email, $password]);
//             ^       ^
//             Donnees envoyees separement
//             Position 1  Position 2

// ETAPE 3 : Recuperer le resultat
$user = $stmt->fetch();

if ($user) {
    echo "Connecte !";
} else {
    echo "Erreur de connexion";
}
?>
💡 Les ? sont remplis dans l'ordre :
Premier ? = Premier élément du tableau
Deuxième ? = Deuxième élément du tableau

Explication étape par étape 🔍

Étape 1 : prepare()
$sql = "SELECT * FROM user WHERE email = ? AND password = ?";
$stmt = $pdo->prepare($sql);

PHP envoie la STRUCTURE à MySQL (sans les données).
MySQL dit : "OK j'ai compris, tu vas me chercher un user avec 2 critères"
Les ? sont des marqueurs = places réservées pour les données

Étape 2 : execute()
$stmt->execute([$email, $password]);

PHP envoie les DONNÉES (email et password).
MySQL remplit les ? avec ces données.
Mais MySQL sait que c'est du TEXTE, jamais du CODE !

Étape 3 : fetch()
$user = $stmt->fetch();

Récupérer le résultat (l'utilisateur trouvé, ou rien)

Marqueurs nommés (alternative) 📛

Au lieu de ?, on peut donner des noms :

<?php
$email = $_POST['email'];
$password = $_POST['password'];

// Marqueurs NOMMES (avec :nom)
$sql = "SELECT * FROM user WHERE email = :email AND password = :pwd";
                                             ^                     ^
                                             Marqueurs nommes

$stmt = $pdo->prepare($sql);

// Execute avec tableau associatif
$stmt->execute([
    ':email' => $email,      // :email sera remplace par $email
    ':pwd' => $password      // :pwd sera remplace par $password
]);

$user = $stmt->fetch();
?>
💡 ? vs :nom :
? → Plus court, mais l'ordre compte
:nom → Plus clair quand il y a beaucoup de paramètres

Pourquoi ça protège ? 🛡️

Sans requete preparee (DANGER) : PHP construit : "... WHERE email = '" + $email + "'" Si $email = "pirate' OR '1'='1" Resultat : "... WHERE email = 'pirate' OR '1'='1'" ^ Code SQL execute ! Avec requete preparee (SECURISE) : PHP envoie structure : "... WHERE email = ?" PHP envoie donnee : "pirate' OR '1'='1" MySQL recoit : Structure : WHERE email = ? Donnee : "pirate' OR '1'='1" MySQL cherche LITTERALEMENT un email = "pirate' OR '1'='1" -> Aucun email ne s'appelle ca ! Pas trouve. -> Le ' OR '1'='1 est du TEXTE, pas du CODE !
✅ Principe de sécurité :
MySQL ne MÉLANGE JAMAIS le code et les données.
Les données restent des DONNÉES, jamais du CODE.

Exemple complet - Recherche sécurisée 🔍

<?php
// Formulaire de recherche de clients
$nom = $_GET['nom'] ?? '';  // Nom tape par l'utilisateur

// ❌ VERSION DANGEREUSE (ne JAMAIS faire ca !)
// $sql = "SELECT * FROM client WHERE nom LIKE '%$nom%'";
// $stmt = $pdo->query($sql);

// ✅ VERSION SECURISEE (requete preparee)
$sql = "SELECT * FROM client WHERE nom LIKE ?";
$stmt = $pdo->prepare($sql);

// Important : ajouter les % DANS le tableau execute, pas dans le SQL
$stmt->execute(["%$nom%"]);
//               ^    ^
//               On ajoute les % pour le LIKE

// Recuperer les resultats
$clients = $stmt->fetchAll();

// Afficher
foreach ($clients as $client) {
    echo $client['nom'] . " - " . $client['email'] . "<br>";
}
?>
💡 Astuce LIKE :
On met "%$nom%" dans execute(), pas dans le SQL !
Ça reste sécurisé car c'est une donnée, pas du code.

✏️ Partie 5

CRUD - Modifier les données

Create, Read, Update, Delete

C'est quoi CRUD ? 🤔

CRUD = Les 4 opérations de base sur les données

Create → Créer (INSERT)
Read → Lire (SELECT)
Update → Modifier (UPDATE)
Delete → Supprimer (DELETE)
📓 Analogie du carnet d'adresses :

C = Ajouter un nouveau contact
R = Regarder les contacts
U = Modifier un numéro de téléphone
D = Effacer un contact
💡 Dans TOUS vos projets : Vous ferez ces 4 opérations !
Blog → Créer/Lire/Modifier/Supprimer des articles
E-commerce → Créer/Lire/Modifier/Supprimer des produits
etc.

CREATE - Ajouter un client ➕

Situation : Un nouveau client s'inscrit sur le site

<?php
// Donnees du formulaire d'inscription
$nom = $_POST['nom'];           // Ex: "Dupont"
$prenom = $_POST['prenom'];     // Ex: "Jean"
$email = $_POST['email'];       // Ex: "jean@email.com"

// INSERT avec requete preparee
$sql = "INSERT INTO client (nom, prenom, email) VALUES (?, ?, ?)";
//      ^                   ^                    ^        ^
//      Commande INSERT     Colonnes             Marqueurs
//      (ajouter)           (quelles colonnes)   (donnees)

$stmt = $pdo->prepare($sql);
$stmt->execute([$nom, $prenom, $email]);

// Recuperer l'ID du nouveau client
$newId = $pdo->lastInsertId();
echo "Client ajoute avec l'ID : $newId";
?>
📝 Explication :
INSERT INTO client → "Ajoute dans la table client"
(nom, prenom, email) → "Dans ces colonnes"
VALUES (?, ?, ?) → "Ces valeurs (marqueurs)"
lastInsertId() → MySQL génère un ID automatique, on le récupère

Ce qui se passe dans MySQL 💾

AVANT l'INSERT :

id nom prenom email
1 Martin Paul paul@email.com
2 Durand Marie marie@email.com

APRÈS l'INSERT :

id nom prenom email
1 Martin Paul paul@email.com
2 Durand Marie marie@email.com
3 Dupont Jean jean@email.com

✅ Nouvelle ligne ajoutée avec ID = 3 (auto-généré)

UPDATE - Modifier un client ✏️

Situation : Le client change son email

<?php
// Donnees du formulaire de modification
$id = $_POST['id'];              // Ex: 3 (quel client ?)
$nouvelEmail = $_POST['email'];  // Ex: "nouveaumail@email.com"

// UPDATE avec requete preparee
$sql = "UPDATE client SET email = ? WHERE id = ?";
//      ^             ^            ^       ^
//      Commande      Quoi         Nouvelle  Condition
//      UPDATE        changer      valeur    (quel client)

$stmt = $pdo->prepare($sql);
$stmt->execute([$nouvelEmail, $id]);

// Verifier si ca a marche
$nb = $stmt->rowCount();  // Nombre de lignes modifiees
if ($nb > 0) {
    echo "Email modifie !";
} else {
    echo "Aucun client trouve avec cet ID";
}
?>
⚠️ ATTENTION au WHERE :
Sans WHERE, TOUS les clients auraient le même email !
Toujours spécifier QUEL client modifier avec WHERE id = ?

DELETE - Supprimer un client 🗑️

Situation : Le client ferme son compte

<?php
// ID du client a supprimer
$id = $_GET['id'];  // Ex: 3

// DELETE avec requete preparee
$sql = "DELETE FROM client WHERE id = ?";
//      ^           ^          ^
//      Commande    Table      Condition (quel client)
//      DELETE

$stmt = $pdo->prepare($sql);
$stmt->execute([$id]);

// Verifier
$nb = $stmt->rowCount();
if ($nb > 0) {
    echo "Client supprime";
} else {
    echo "Client introuvable";
}
?>
💀 DANGER :
Sans WHERE → DELETE FROM client
= Supprime TOUS les clients ! 😱
Toujours mettre WHERE pour cibler UN client !

Récapitulatif CRUD 📝

Opération SQL Code PHP
CREATE INSERT INTO $pdo->lastInsertId() pour l'ID
READ SELECT fetch() ou fetchAll()
UPDATE UPDATE...SET...WHERE rowCount() pour vérifier
DELETE DELETE...WHERE rowCount() pour vérifier
🎯 Règle d'or :
TOUJOURS utiliser des requêtes préparées avec prepare() et execute() !
JAMAIS mettre les variables directement dans le SQL !

🎉 Récapitulatif Final

Ce qu'on a appris :
  1. ✅ Se connecter avec PDO (new PDO())
  2. ✅ Récupérer des données (SELECT + fetch())
  3. ✅ Le DANGER de l'injection SQL
  4. ✅ Se protéger avec prepare() + execute()
  5. ✅ CRUD : Create, Read, Update, Delete
💡 Les 3 commandements du débutant :
1️⃣ Toujours utiliser PDO (pas mysql_* ou mysqli)
2️⃣ Toujours utiliser prepare() pour les variables
3️⃣ Toujours gérer les erreurs avec try/catch

Vous êtes prêts à coder avec des bases de données ! 🚀

Merci ! 👏

Des questions ?

🐘 La pratique, c'est maintenant !

Faites des exercices, faites des erreurs, apprenez ! 💪