Une application web stocke presque toujours ses données dans une base : comptes, produits, commandes… En PHP, la façon moderne et standard d’y accéder est PDO (PHP Data Objects). PDO offre la même API quel que soit le système de gestion de base de données (SGBD) : MySQL/MariaDB, PostgreSQL, SQLite, SQL Server… Chaque SGBD est géré par un pilote (pdo_mysql, pdo_pgsql, pdo_sqlite). Vous pouvez vérifier ceux qui sont installés avec php -m.
Le DSN : l’adresse de la base
On crée une connexion en instanciant la classe PDO avec un DSN (Data Source Name), puis éventuellement un utilisateur, un mot de passe et des options.
// SQLite en mémoire : idéal pour apprendre et pour les tests
$pdo = new PDO('sqlite::memory:');
// SQLite dans un fichier
$pdo = new PDO('sqlite:' . __DIR__ . '/app.sqlite');
// MySQL / MariaDB : toujours préciser charset=utf8mb4
$pdo = new PDO('mysql:host=127.0.0.1;port=3306;dbname=boutique;charset=utf8mb4', 'app', 'secret');
// PostgreSQL
$pdo = new PDO('pgsql:host=127.0.0.1;port=5432;dbname=boutique', 'app', 'secret');
Les options indispensables
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // une erreur SQL lève une exception
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // lignes sous forme de tableaux associatifs
PDO::ATTR_EMULATE_PREPARES => false, // vraies requêtes préparées (MySQL)
];
$pdo = new PDO($dsn, $user, $password, $options);
Depuis PHP 8.0, le mode d’erreur par défaut est déjà ERRMODE_EXCEPTION, mais l’écrire explicitement rend le code lisible et robuste. Sans exception, une requête fautive renverrait simplement false, et l’erreur passerait inaperçue.
Gérer l’échec de connexion
try {
$pdo = new PDO($dsn, getenv('DB_USER'), getenv('DB_PASSWORD'), $options);
} catch (PDOException $e) {
error_log($e->getMessage()); // on journalise le détail
http_response_code(500);
exit('Service momentanément indisponible.'); // message neutre pour l'utilisateur
}
Le message d’une PDOException peut révéler le nom de l’hôte ou de la base : on le journalise, on ne l’affiche pas. De même, le mot de passe ne doit jamais apparaître dans le code versionné : lisez-le depuis une variable d’environnement (getenv(), $_ENV) ou un fichier .env ignoré par Git.
Exécuter une première instruction
Pour une instruction sans paramètre et sans résultat (création de table, par exemple), exec() suffit. Elle renvoie le nombre de lignes affectées.
$pdo->exec('CREATE TABLE produits (
id INTEGER PRIMARY KEY AUTOINCREMENT,
nom TEXT NOT NULL,
prix REAL NOT NULL
)');
Bon à savoir : depuis PHP 8.4,
PDO::connect($dsn, ...)renvoie une sous-classe propre au pilote (Pdo\Sqlite,Pdo\Mysql…).new PDO(...)reste valable et c’est ce que vous rencontrerez le plus souvent. PHP 8.5 déprécie en revanche les constantes propres à un pilote déclarées surPDO(par exemplePDO::SQLITE_ATTR_OPEN_FLAGS) : utilisez celles de la sous-classe (Pdo\Sqlite::ATTR_OPEN_FLAGS,Pdo\Mysql::ATTR_...).
En résumé : un DSN correct, des options explicites, des identifiants hors du code et une gestion d’erreur discrète. C’est la base de tout le reste du cours.
Exercices
Les solutions et les tests restent sur le serveur. Dans l'espace étudiant, ton code est exécuté et corrigé, et le tuteur donne des indices avant la solution.
Créer une connexion configurée
Écrivez une fonction
connecter(): PDOqui renvoie une connexion SQLite en mémoire configurée avec :- le mode d’erreur
PDO::ERRMODE_EXCEPTION; - le mode de récupération par défaut
PDO::FETCH_ASSOC.
function connecter(): PDO { // À compléter }- le mode d’erreur
Créer et remplir une table
Écrivez une fonction
initialiser(PDO $pdo): voidqui :- crée une table
clients(idINTEGER PRIMARY KEY AUTOINCREMENT,nomTEXT NOT NULL,villeTEXT NOT NULL) ; - insère trois clients : Alice (Lyon), Bruno (Lille), Chloé (Lyon).
Utilisez
exec().function initialiser(PDO $pdo): void { // CREATE TABLE puis INSERT }- crée une table
Choisir le bon DSN
Quel DSN permet de se connecter à la base MySQL
boutiquesur la machine locale avec un encodage complet (accents et emojis) ?- mysql:host=127.0.0.1;dbname=boutique;charset=utf8mb4
- mysql://127.0.0.1/boutique?charset=utf8
- sqlite:boutique;charset=utf8mb4
- mysql:host=127.0.0.1;database=boutique
Quiz de fin de leçon
Que se passe-t-il, avec PDO::ERRMODE_EXCEPTION, si une requête SQL contient une erreur de syntaxe ?
- La méthode renvoie false silencieusement
- Une PDOException est levée
- PHP affiche un avertissement et continue
Quelle méthode utiliser pour exécuter un CREATE TABLE sans paramètre ?
- exec()
- fetch()
- lastInsertId()
Où ranger le mot de passe de la base de données ?
- Dans le code PHP, en constante
- Dans une variable d'environnement ou un fichier .env non versionné
- Dans un commentaire HTML
La suite du cours
- Lire des données : query, fetch et fetchAll15 min
- Requêtes préparées et injection SQL20 min
- Insérer, modifier, supprimer et transactions20 min
- Organiser l'accès aux données : entités et repository20 min