Aller au contenu
M07 · C. Manipuler les données

Se connecter à MySQL avec PDO

Le rôle de PDO, la chaîne de connexion (DSN), les identifiants, la gestion des erreurs avec try/catch, un fichier de connexion commun, puis les premières lectures avec query, fetch, fetchAll et fetchColumn.

1Situer

Jusqu'ici, les produits de Souk Atlas étaient écrits en dur dans le code PHP. Dans un vrai site, ils vivent dans la base MySQL construite au module 06. Pour que PHP puisse lui parler, il lui faut une connexion : c'est le travail de PDO, l'extension activée à la leçon A.3.

2Comprendre

new PDO : trois vérifications avant de pouvoir parler à la base
Script PHP new PDO( host=localhost port=3306 dbname=souk 'root', '' ) $pdo ✔ Serveur MySQL :3306 1. serveur joignable ?… 2. compte accepté ?… 3. base existante ?… souk : produits, clients…

new PDO('mysql:host=localhost;port=3306;dbname=souk', 'root', '') : PHP lit le DSN puis contacte le serveur.

1 / 5

PDO, l’interface vers la base

Il existe aussi l’extension mysqli, propre à MySQL. PDO est préférée aujourd’hui parce qu’elle est la même pour tous les SGBD et que ses requêtes préparées (leçon C.2) sont simples à écrire.

Dans XAMPP, l’extension se nomme pdo_mysql. Si new PDO('mysql:...') répond « could not find driver », elle n’est pas activée dans php.ini (leçon A.3).

La connexion

<?php
$dsn = 'mysql:host=localhost;port=3306;dbname=souk;charset=utf8mb4';
$pdo = new PDO($dsn, 'root', '');   // utilisateur, mot de passe

Sous XAMPP, l’utilisateur root n’a pas de mot de passe : on passe une chaîne vide. Chez un hébergeur, on reçoit un utilisateur et un mot de passe dédiés, et on ne se connecte jamais en root.

Les options de la connexion

On règle le comportement de PDO avec setAttribute, ou directement avec un quatrième argument :

$pdo = new PDO($dsn, 'root', '', [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION, // une erreur SQL lance une exception
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,       // lignes en tableaux associatifs
]);
  • ERRMODE_EXCEPTION est le mode par défaut depuis PHP 8 : une requête fausse lance une PDOException au lieu d’échouer en silence. On l’écrit quand même, le code reste clair pour qui le relit.
  • FETCH_ASSOC donne des lignes ['nom' => ..., 'prix' => ...]. Sans lui, PDO renvoie chaque valeur deux fois (par nom et par numéro de colonne).

Lire des données

Fermer la connexion

PHP ferme la connexion tout seul à la fin du script. Pour la fermer plus tôt, on écrit $pdo = null;. Il n’y a rien d’autre à faire.

Exemple simple

Le standard téléphonique

Pour joindre un service, on compose un numéro (le DSN : quel serveur, quelle base), on se présente (utilisateur et mot de passe), puis on parle. PDO est le combiné : le même appareil sert pour MySQL, PostgreSQL ou SQLite.

Exemple simple

Le guichet de la poste

On tend un formulaire au guichet (la requête SQL), l'agent revient avec une liasse de fiches (les lignes). On peut les prendre une par une (fetch) ou toutes d'un coup (fetchAll).

3Manipuler

Le site doit lire la base souk du serveur MySQL local (utilisateur root, sans mot de passe). La connexion échoue : corrigez-la, puis complétez la page.
Pas à pas dans le lab ↗ Cliquez sur Exécuter : PHP 8.3 démarre dans votre navigateur (environ 5 Mo à télécharger, une seule fois).

La page s'affichera ici.

Le navigateur demandera /index.php au serveur, qui exécutera le PHP et renverra du HTML.

Entre le navigateur et le serveur aucun échange pour l'instant

Consignes 0 / 3

  1. La connexion réussit : plus de « Connexion impossible »
  2. « 12 produits au catalogue »
  3. La liste des ruptures : Plat à couscous et Eau de rose

4Pratiquer

Exercice 1 · Les villes

Avec db.php, affichez la liste des villes (nom et région) triées par nom dans un tableau HTML.

Voir le corrigé
<?php
require __DIR__ . '/db.php';
$villes = $pdo->query('SELECT nom, region FROM villes ORDER BY nom')->fetchAll();
?>
<table>
  <tr><th>Ville</th><th>Région</th></tr>
  <?php foreach ($villes as $v): ?>
    <tr><td><?= htmlspecialchars($v['nom']) ?></td><td><?= htmlspecialchars($v['region']) ?></td></tr>
  <?php endforeach; ?>
</table>

Exercice 2 · Le produit le plus cher

Récupérez une seule ligne, le produit le plus cher, avec fetch(), et affichez « Le plus cher : Tapis berbère (1 200,00 DH) ».

Voir le corrigé
<?php
require __DIR__ . '/db.php';
$p = $pdo->query('SELECT nom, prix FROM produits ORDER BY prix DESC LIMIT 1')->fetch();
echo "Le plus cher : {$p['nom']} (" . number_format($p['prix'], 2, ',', ' ') . " DH)";

Exercice 3 · Lire le message d'erreur

Pour chacun de ces messages, dites ce qui ne va pas : « [1045] Access denied for user 'root'@'localhost' (using password: YES) », « [1049] Unknown database 'souk_atlas' », « [2002] No connection could be made... ».

Voir le corrigé
1045 : le serveur répond, mais l'utilisateur ou le mot de passe est faux (ici, un mot de passe a été donné alors que root n'en a pas).
1049 : on est bien connecté à MySQL, mais la base demandée n'existe pas (faute de frappe dans dbname, ou base pas encore importée).
2002 : aucun serveur MySQL ne répond à cette adresse ou ce port (MySQL arrêté dans XAMPP, mauvais host, mauvais port).

5Vérifier

1. Dans 'mysql:host=localhost;dbname=souk;charset=utf8mb4', que désigne dbname ?
2. Quelle méthode renvoie directement la valeur de la première colonne, par exemple le résultat d'un COUNT(*) ?
3. Pourquoi placer la connexion dans un fichier db.php inclus par les autres pages ?