PHP : bases de données avec PDO
PDO (PHP Data Objects) est l’interface commune d’accès aux bases de données. Les exemples reprennent la base fictive boutique (tables clients et commandes).
Extensions nécessaires
Section intitulée « Extensions nécessaires »sudo apt install php-mysql # MariaDB et MySQLsudo apt install php-pgsql # PostgreSQLsudo apt install php-sqlite3 # SQLitephp -m | grep -i pdoRecharger PHP-FPM après l’installation (sudo systemctl reload php8.3-fpm).
Connexion
Section intitulée « Connexion »<?phpdeclare(strict_types=1);
$pdo = new PDO( 'mysql:host=127.0.0.1;dbname=boutique;charset=utf8mb4', 'app', getenv('DB_PASSWORD'), [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ],);| Base | DSN |
|---|---|
| MariaDB / MySQL | mysql:host=127.0.0.1;dbname=boutique;charset=utf8mb4 |
| PostgreSQL | pgsql:host=127.0.0.1;port=5432;dbname=boutique |
| SQLite | sqlite:/var/www/monapp/donnees/boutique.db |
Le mot de passe provient de l’environnement, jamais du code. Créer le compte app avec des droits limités : voir MariaDB : utilisateurs et droits ou PostgreSQL : utilisateurs et droits.
Requêtes préparées
Section intitulée « Requêtes préparées »<?php$stmt = $pdo->prepare('SELECT id, nom, email FROM clients WHERE email = :email');$stmt->execute(['email' => $email]);$client = $stmt->fetch(); // une ligne ou false
$stmt = $pdo->prepare('SELECT * FROM commandes WHERE client_id = ? AND total > ?');$stmt->execute([$clientId, 100]);$commandes = $stmt->fetchAll(); // toutes les lignesLes noms de tables et de colonnes ne se lient pas : les valider contre une liste autorisée.
<?php$stmt = $pdo->prepare('INSERT INTO clients (nom, email) VALUES (:nom, :email)');$stmt->execute(['nom' => 'Alice', 'email' => 'alice@exemple.com']);$id = $pdo->lastInsertId();
$stmt = $pdo->prepare('UPDATE clients SET actif = :actif WHERE id = :id');$stmt->execute(['actif' => 0, 'id' => $id]);echo $stmt->rowCount(), " ligne(s)\n";Transactions
Section intitulée « Transactions »<?phptry { $pdo->beginTransaction(); $pdo->prepare('UPDATE commandes SET statut = ? WHERE id = ?')->execute(['payee', 10]); $pdo->prepare('INSERT INTO journal (message) VALUES (?)')->execute(['commande 10 payée']); $pdo->commit();} catch (Throwable $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } throw $e;}Gérer les erreurs
Section intitulée « Gérer les erreurs »Avec PDO::ERRMODE_EXCEPTION, une erreur SQL lève une PDOException :
<?phptry { $pdo->query('SELECT * FROM table_inexistante');} catch (PDOException $e) { error_log($e->getMessage()); // dans le journal, pas dans la page http_response_code(500); echo 'Erreur interne.';}Ne pas afficher le message SQL aux visiteurs.
Parcourir de gros résultats
Section intitulée « Parcourir de gros résultats »<?php$stmt = $pdo->query('SELECT id, nom FROM clients');while ($ligne = $stmt->fetch()) { echo $ligne['nom'], "\n";}Parcourir ligne par ligne évite de charger toute la table en mémoire (contrairement à fetchAll).
<?php$pdo = new PDO('sqlite:/var/www/monapp/donnees/boutique.db');$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);$pdo->exec('PRAGMA journal_mode = WAL');$pdo->exec('PRAGMA foreign_keys = ON');Le dossier et le fichier doivent être modifiables par l’utilisateur de PHP-FPM (SQLite crée des fichiers annexes à côté de la base). Voir SQLite : installation.
Dépannage
Section intitulée « Dépannage »| Symptôme | Piste |
|---|---|
could not find driver |
Extension manquante (php-mysql, php-pgsql, php-sqlite3) ou PHP-FPM non rechargé |
SQLSTATE[HY000] [2002] Connection refused |
Serveur arrêté, mauvais hôte ou port |
SQLSTATE[HY000] [1045] Access denied |
Identifiants ou hôte du compte incorrects |
SQLSTATE[HY000] [2002] No such file or directory |
Avec localhost, PHP utilise un socket : utiliser 127.0.0.1 ou indiquer unix_socket= |
attempt to write a readonly database (SQLite) |
Droits sur le dossier ou le fichier |
SQLSTATE[23000] Duplicate entry |
Violation d’une contrainte unique |
Ubuntu 24.04 et 26.04 : différences à connaître
Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »PDO fonctionne de la même manière en PHP 8.3 et 8.5. Sur 26.04, le serveur fourni est MariaDB 11.8 (voir MariaDB : installation) : le pilote php-mysql s’y connecte sans changement.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Manuel PDO
- Suite : Dépannage