PHP MySQLi
Apprenez l'extension PHP MySQLi : connexion à MySQL, requêtes sécurisées avec les instructions préparées, gestion des erreurs, et comparaison MySQLi/PDO.
MySQLi (« MySQL Improved ») est l'extension PHP utilisée pour se connecter à une base de données MySQL ou MariaDB, exécuter des requêtes et lire les résultats. Cet article explique ce qu'est l'extension, comment se connecter, comment exécuter des requêtes SELECT/INSERT/UPDATE en toute sécurité, et quand utiliser MySQLi plutôt que PDO.
Qu'est-ce que l'extension MySQLi ?
L'extension MySQLi est le successeur des anciennes fonctions mysql_* (désormais supprimées). Elle ajoute des fonctionnalités absentes de l'extension originale : les instructions préparées, les transactions, les instructions multiples et une prise en charge correcte de l'authentification MySQL 4.1+. Elle est fournie avec PHP et activée par défaut sur la plupart des installations.
MySQLi expose les mêmes fonctionnalités à travers deux interfaces :
- Orientée objet — vous travaillez avec un objet
mysqliet appelez des méthodes comme$mysqli->query(). C'est le style utilisé par la plupart du code moderne, et celui suivi dans cet article. - Procédurale — vous appelez des fonctions comme
mysqli_connect()etmysqli_query()en passant la connexion comme premier argument.
Les deux font exactement la même chose ; choisissez-en une et restez cohérent. La forme orientée objet est plus concise et se lit plus naturellement.
Connexion à une base de données
Une connexion est représentée par un objet mysqli. Vous en créez un en passant l'hôte, le nom d'utilisateur, le mot de passe et le nom de la base de données au constructeur, puis vous vérifiez que la connexion a réussi avant de faire quoi que ce soit d'autre :
<?php
$mysqli = new mysqli("localhost", "username", "password", "my_database");
// Always check the connection before using it.
if ($mysqli->connect_error) {
die("Failed to connect to MySQL: " . $mysqli->connect_error);
}
// Recommended: use UTF-8 so accented characters and emoji are stored correctly.
$mysqli->set_charset("utf8mb4");
echo "Connected successfully";
?>La propriété connect_error contient un message lisible par l'humain lorsque la connexion échoue (ou null en cas de succès). Appeler set_charset() juste après la connexion évite des bugs d'encodage subtils par la suite. Pour un examen plus approfondi de l'ouverture d'une connexion, consultez PHP mysqli_connect() et la référence connect().
Exécution d'une requête SELECT
Une fois connecté, query() exécute du SQL et renvoie un objet résultat que vous pouvez parcourir. fetch_assoc() retourne une ligne à la fois sous forme de tableau associatif, ou null lorsqu'il n'y a plus de lignes :
<?php
$result = $mysqli->query("SELECT name, email FROM users");
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
}
} else {
echo "No users found.";
}
$result->free(); // release the result set
$mysqli->close(); // close the connection when you are done
?>num_rows indique le nombre de lignes retournées, ce qui vous permet d'afficher un message convivial lorsqu'une requête ne retourne rien. Consultez PHP MySQL Select Data pour d'autres modèles de requêtes.
Les instructions préparées (la manière sûre d'utiliser les entrées)
Ne collez jamais directement les entrées utilisateur dans une chaîne de requête — c'est ainsi que se produit l'injection SQL. Une instruction préparée envoie le SQL et les données séparément, de sorte que la base de données traite les entrées strictement comme une valeur et jamais comme du SQL exécutable.
Vous écrivez des espaces réservés ?, prepare() l'instruction, puis bind_param() les valeurs réelles :
<?php
$age = 18;
$stmt = $mysqli->prepare("SELECT name, email FROM users WHERE age > ?");
$stmt->bind_param("i", $age); // "i" = integer (s = string, d = double, b = blob)
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo "Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
}
$stmt->close();
?>Le premier argument de bind_param() est une chaîne de types : un caractère par espace réservé — i (integer), s (string), d (double/float), ou b (blob). Les arguments suivants sont les valeurs, dans l'ordre.
Remarque :
get_result()nécessite le pilotemysqlnd, qui est le pilote par défaut dans les versions modernes de PHP. Si votre installation ne l'inclut pas, utilisezbind_result()pour lier les colonnes à des variables à la place.
Pour un guide dédié, consultez PHP MySQL Prepared Statements.
Insertion et mise à jour de données
Le même modèle d'instruction préparée fonctionne pour les écritures. Après un INSERT, l'identifiant auto-incrémenté de la nouvelle ligne est disponible via $mysqli->insert_id ; après un INSERT/UPDATE/DELETE, $mysqli->affected_rows indique combien de lignes ont été modifiées :
<?php
$name = "Ada Lovelace";
$email = "[email protected]";
$stmt = $mysqli->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->bind_param("ss", $name, $email); // two strings
$stmt->execute();
echo "Inserted user #" . $mysqli->insert_id;
$stmt->close();
?>Consultez PHP MySQL Insert Data et PHP MySQL Update Data pour une vue complète des opérations CRUD.
Gestion des erreurs
Si une requête échoue, query() retourne false et les détails sont disponibles sur l'objet de connexion. Lire $mysqli->error après un appel échoué vous indique ce qui s'est passé :
<?php
if (!$mysqli->query("SELECT * FROM no_such_table")) {
echo "Query failed (" . $mysqli->errno . "): " . $mysqli->error;
}
?>En développement, vous pouvez faire en sorte que MySQLi lève automatiquement des exceptions avec mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT), ce qui est le comportement par défaut depuis PHP 8.1. Lectures connexes : PHP connect_error et PHP connect_errno.
MySQLi vs. PDO — lequel utiliser ?
Les deux sont des moyens sûrs et modernes de communiquer avec une base de données. En résumé :
- MySQLi ne fonctionne qu'avec MySQL/MariaDB. Il expose certaines fonctionnalités spécifiques à MySQL (comme les requêtes asynchrones) que PDO n'offre pas.
- PDO (PHP Data Objects) prend en charge une douzaine de bases de données via une seule API, donc passer de MySQL à PostgreSQL signifie changer une chaîne de connexion, pas vos requêtes. Il prend également en charge les espaces réservés nommés (
:name) qui sont plus faciles à lire.
Si vous savez que vous n'utiliserez que MySQL, MySQLi convient parfaitement. Si la portabilité est importante, préférez PDO. Dans tous les cas, utilisez toujours les instructions préparées.
Résumé
- MySQLi est l'extension standard pour travailler avec MySQL/MariaDB en PHP, disponible en styles orienté objet et procédural.
- Créez une connexion avec
new mysqli(...), vérifiezconnect_erroret définissez le jeu de caractères. - Utilisez
query()+fetch_assoc()pour lire les données et parcourir les résultats. - Utilisez les instructions préparées (
prepare()→bind_param()→execute()) pour tout ce qui implique des entrées utilisateur afin de rester protégé contre l'injection SQL. - Vérifiez
$mysqli->error/$mysqli->errnolorsqu'une requête échoue, et préférez PDO si vous avez besoin de portabilité entre bases de données.