Pourquoi connecter PHP à MySQL ?
Applications dynamiques
- Stockage persistant des données
- Gestion des utilisateurs et authentification
- Contenu personnalisé pour chaque visiteur
- Applications complexes (blogs, e-commerce, etc.)
Architecture typique
Client (Navigateur) → PHP (Serveur) → MySQL (Base de données)
PHP agit comme intermédiaire entre l'utilisateur et la base de données.
1. Connexion à MySQL avec PHP
Méthodes de connexion
Ancienne méthode (dépréciée)
<?php
// À ÉVITER - Non sécurisé et déprécié
$conn = mysql_connect('localhost', 'user', 'pass');
mysql_select_db('ma_bdd');
?>
Vulnérable aux injections SQL. Ne plus utiliser.
Méthode recommandée (PDO)
<?php
try {
$pdo = new PDO(
'mysql:host=localhost;dbname=ma_bdd;charset=utf8',
'user',
'pass',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
} catch (PDOException $e) {
die("Erreur connexion : " . $e->getMessage());
}
?>
Sécurisé, supporte plusieurs SGBD, gestion d'erreurs.
Bonnes pratiques
- Utilisez PDO (PHP Data Objects) pour sa sécurité et flexibilité
- Placez les informations de connexion dans un fichier séparé (config.php)
- Ne stockez jamais les mots de passe en clair dans le code
- Utilisez le charset UTF-8 pour supporter tous les caractères
- Activez le mode erreur avec
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
2. Requêtes Préparées
Pourquoi utiliser des requêtes préparées ?
Sécurité
Protection contre les injections SQL, une des vulnérabilités les plus critiques.
Sans requête préparée
// DANGEREUX - Injection SQL possible
$sql = "SELECT * FROM users WHERE id = $id";
Avec requête préparée
// SÉCURISÉ - Les données sont échappées
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$id]);
Performance
Meilleures performances pour les requêtes répétitives.
- Le plan d'exécution est compilé une seule fois
- Seules les données changent entre les exécutions
- Réduction de la charge serveur
Types de requêtes préparées
SELECT
INSERT
UPDATE
DELETE
<?php
// Préparation
$stmt = $pdo->prepare("SELECT * FROM articles WHERE categorie = ? AND publie = ?");
// Exécution avec paramètres
$stmt->execute(['technologie', 1]);
// Récupération des résultats
$articles = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Utilisation
foreach ($articles as $article) {
echo "<h2>{$article['titre']}</h2>";
}
?>
<?php
// Préparation
$stmt = $pdo->prepare("INSERT INTO utilisateurs
(nom, email, mot_de_passe)
VALUES (?, ?, ?)");
// Exécution avec paramètres
$success = $stmt->execute([
'Alice',
'alice@exemple.com',
password_hash('monmotdepasse', PASSWORD_DEFAULT)
]);
// Vérification
if ($success) {
$id = $pdo->lastInsertId();
echo "Nouvel ID : $id";
}
?>
<?php
// Préparation
$stmt = $pdo->prepare("UPDATE articles
SET titre = ?, contenu = ?
WHERE id = ?");
// Exécution avec paramètres
$success = $stmt->execute([
'Nouveau titre',
'Nouveau contenu...',
42
]);
// Vérification
if ($success) {
echo "{$stmt->rowCount()} ligne(s) modifiée(s)";
}
?>
<?php
// Préparation
$stmt = $pdo->prepare("DELETE FROM commentaires
WHERE id = ? AND utilisateur_id = ?");
// Exécution avec paramètres
$success = $stmt->execute([15, 42]);
// Vérification
if ($success && $stmt->rowCount() > 0) {
echo "Commentaire supprimé";
} else {
echo "Erreur ou aucun commentaire supprimé";
}
?>
3. CRUD Complet avec PHP/MySQL
Application de gestion d'articles
Structure de la table
CREATE TABLE articles (
id INT AUTO_INCREMENT PRIMARY KEY,
titre VARCHAR(255) NOT NULL,
contenu TEXT NOT NULL,
date_creation DATETIME DEFAULT CURRENT_TIMESTAMP,
date_modification DATETIME ON UPDATE CURRENT_TIMESTAMP,
auteur_id INT NOT NULL,
FOREIGN KEY (auteur_id) REFERENCES utilisateurs(id)
);
Fichier de configuration
<?php
// config.php
return [
'db' => [
'host' => 'localhost',
'dbname' => 'monblog',
'user' => 'root',
'pass' => '',
'charset' => 'utf8mb4'
]
];
Implémentation du CRUD
Create - Création d'un article
<?php
// create_article.php
require 'config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$titre = $_POST['titre'] ?? '';
$contenu = $_POST['contenu'] ?? '';
$auteurId = $_SESSION['user_id'] ?? 0;
try {
$pdo = new PDO(
"mysql:host={$config['db']['host']};dbname={$config['db']['dbname']};charset={$config['db']['charset']}",
$config['db']['user'],
$config['db']['pass'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$stmt = $pdo->prepare("INSERT INTO articles
(titre, contenu, auteur_id)
VALUES (?, ?, ?)");
$stmt->execute([$titre, $contenu, $auteurId]);
header("Location: article.php?id=" . $pdo->lastInsertId());
exit;
} catch (PDOException $e) {
die("Erreur : " . $e->getMessage());
}
}
?>
Read - Lecture d'articles
<?php
// list_articles.php
require 'config.php';
try {
$pdo = new PDO(...); // Voir connexion précédente
// Récupérer tous les articles
$stmt = $pdo->query("SELECT * FROM articles ORDER BY date_creation DESC");
$articles = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Afficher les articles
foreach ($articles as $article) {
echo "<article>";
echo "<h2>{$article['titre']}</h2>";
echo "<p>{$article['contenu']}</p>";
echo "</article>";
}
} catch (PDOException $e) {
die("Erreur : " . $e->getMessage());
}
?>
Update - Modification d'un article
<?php
// update_article.php
require 'config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$id = $_POST['id'] ?? 0;
$titre = $_POST['titre'] ?? '';
$contenu = $_POST['contenu'] ?? '';
$auteurId = $_SESSION['user_id'] ?? 0;
try {
$pdo = new PDO(...); // Voir connexion précédente
// Vérifier que l'auteur est bien le propriétaire
$stmt = $pdo->prepare("SELECT id FROM articles
WHERE id = ? AND auteur_id = ?");
$stmt->execute([$id, $auteurId]);
if ($stmt->rowCount() === 0) {
die("Article non trouvé ou non autorisé");
}
// Mettre à jour l'article
$stmt = $pdo->prepare("UPDATE articles
SET titre = ?, contenu = ?
WHERE id = ?");
$stmt->execute([$titre, $contenu, $id]);
header("Location: article.php?id=$id");
exit;
} catch (PDOException $e) {
die("Erreur : " . $e->getMessage());
}
}
?>
Delete - Suppression d'un article
<?php
// delete_article.php
require 'config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$id = $_POST['id'] ?? 0;
$auteurId = $_SESSION['user_id'] ?? 0;
try {
$pdo = new PDO(...); // Voir connexion précédente
// Vérifier les droits
$stmt = $pdo->prepare("SELECT id FROM articles
WHERE id = ? AND auteur_id = ?");
$stmt->execute([$id, $auteurId]);
if ($stmt->rowCount() === 0) {
die("Article non trouvé ou non autorisé");
}
// Supprimer l'article
$stmt = $pdo->prepare("DELETE FROM articles WHERE id = ?");
$stmt->execute([$id]);
header("Location: articles.php");
exit;
} catch (PDOException $e) {
die("Erreur : " . $e->getMessage());
}
}
?>
Exercice Pratique
Système de gestion de tâches
Créez une application de gestion de tâches avec :
- Une base de données avec une table
taches
- Un script PHP pour ajouter des tâches
- Une page pour lister toutes les tâches
- La possibilité de marquer une tâche comme terminée
- La possibilité de supprimer des tâches
- Une protection contre les injections SQL
Solution Guidée
1. Structure de la table
CREATE TABLE taches (
id INT AUTO_INCREMENT PRIMARY KEY,
description VARCHAR(255) NOT NULL,
date_creation DATETIME DEFAULT CURRENT_TIMESTAMP,
termine BOOLEAN DEFAULT FALSE,
utilisateur_id INT NOT NULL,
FOREIGN KEY (utilisateur_id) REFERENCES utilisateurs(id)
);
2. Ajout d'une tâche
<?php
// ajouter_tache.php
require 'config.php';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$description = $_POST['description'] ?? '';
$utilisateurId = $_SESSION['user_id'] ?? 0;
try {
$pdo = new PDO(...); // Configuration comme précédemment
$stmt = $pdo->prepare("INSERT INTO taches
(description, utilisateur_id)
VALUES (?, ?)");
$stmt->execute([$description, $utilisateurId]);
header("Location: taches.php");
exit;
} catch (PDOException $e) {
die("Erreur : " . $e->getMessage());
}
}
?>
3. Liste des tâches
<?php
// taches.php
require 'config.php';
$utilisateurId = $_SESSION['user_id'] ?? 0;
try {
$pdo = new PDO(...);
$stmt = $pdo->prepare("SELECT * FROM taches
WHERE utilisateur_id = ?
ORDER BY termine ASC, date_creation DESC");
$stmt->execute([$utilisateurId]);
$taches = $stmt->fetchAll();
foreach ($taches as $tache) {
$status = $tache['termine'] ? 'Terminé' : 'En cours';
echo "<div class='tache'>";
echo "<p>{$tache['description']} ($status)</p>";
echo "<a href='terminer_tache.php?id={$tache['id']}'>Terminer</a>";
echo "<a href='supprimer_tache.php?id={$tache['id']}'>Supprimer</a>";
echo "</div>";
}
} catch (PDOException $e) {
die("Erreur : " . $e->getMessage());
}
?>