Rappel : si vous travaillez sur votre ordinateur personnel, vous devez avoir créer la base de données de test pour que les exemples puissent être utilisés.

Quelle que soit la phase de traitement il est primordial de gérer les erreurs qui peuvent se produire avec la base de données.

Les erreurs empêchant une connexion correcte doivent être traitées immédiatement sinon des erreurs en cascade se produiront car toutes les requêtes ennoyées au serveur MySQL échoueront.

Dans l'exemple suivant, nous tentons une connexion avec un mauvais mot de passe pour examiner ce qui se passe dans le cas d'une erreur.

Exemple : erreur de connexion
<?php ob_start(); require('bib_fonctions.php'); htmlDebut('Erreur de connexion'); //-- Connexion -------------------------------------- $bd = mysqli_connect('localhost', 'tuto_user', 'mauvais', 'php_tuto'); //-- Requête ---------------------------------------- $sql = 'SELECT count(*) FROM livres'; $r = mysqli_query($bd, $sql); //-- Traitement ------------------------------------- $enr = mysqli_fetch_row($r); echo 'Il y a ', $enr[0], ' livres dans notre base'; // Libération de la mémoire associée au résultat de la requête mysqli_free_result($r); //-- Déconnexion ------------------------------------ mysqli_close($bd); htmlFin(); ?>

Comme nous pouvons le constater une erreur de connexion n'arrête pas le déroulement du script, et entraîne de nombreuses erreurs en cascade. Pour un utilisateur non averti, ces messages sont particulièrement déstabilisants. Pour un utilisateur averti, et c'est pire, ces messages donnent des informations sur le serveur de la base de données, et les répertoires du serveur Web.
Exemple : le nom d'utilisateur apparait dans
Warning: mysqli_connect() ... : Access denied for user 'tuto_user'@'localhost'...

Pour cacher les messages d'erreurs, PHP propose une solution pratique et simple à mettre en oeuvre : il suffit d'ajouter le caractère @ (arobase) devant la fonction.

Attention : cacher un message d'erreur ne supprime pas l'erreur.

Ci dessous notre script modifié :

Exemple : erreur de connexion
<?php ob_start(); require('bib_fonctions.php'); htmlDebut('Nombre de livres'); //-- Connexion -------------------------------------- $bd = @mysqli_connect('localhost', 'tuto_user', 'mauvais', 'php_tuto'); //-- Requête ---------------------------------------- $sql = 'SELECT count(*) FROM livres'; $r = @mysqli_query($bd, $sql); //-- Traitement ------------------------------------- $enr = @mysqli_fetch_row($r); echo 'Il y a ', $enr[0], ' livres dans notre base'; // Libération de la mémoire associé au résultat de la requête @mysqli_free_result($r); //-- Déconnexion ------------------------------------ @mysqli_close($bd); htmlFin(); ?>

Plus aucun message d'erreur ... Mais le résultat ('Il y a livres dans notre base') peut laisser perplexe. De plus si l'utilisation de @ est facile, elle devient vite fastidieuse s'il faut préfixer toutes les fonctions. Et surtout : les erreurs sont toujours là.

Ce qui nous importe pour le moment, c'est uniquement la partie connexion : si la connexion échoue nous devons arrêter le traitement de la page en prévenant l'utilisateur avec un message facilement compréhensible.

Si la connexion échoue, la fonction mysqli_connect() renvoie FALSE. Nous pouvons donc tester le résultat de la fonction et définir un traitement particulier si elle échoue. Par exemple :

Exemple : erreur de connexion
<?php ob_start(); require('bib_fonctions.php'); //-- Début du script -------------------------------- htmlDebut('Nombre de livres'); //-- Connexion -------------------------------------- $bd = mysqli_connect('localhost', 'tuto_user', 'mauvais', 'php_tuto'); if ($bd === FALSE) { ob_end_clean(); // Supression de tout ce qui // a pu être déja généré htmlDebut('Maintenance en cours'); // Gros mensonge echo 'Notre site est momentanément indisponible ', 'pour cause de maintenance. Merci de ré-essayer ', 'dans quelques instants.'; htmlFin(); exit(); // Fin du script } //-- Requête ---------------------------------------- $sql = 'SELECT count(*) FROM livres'; $r = mysqli_query($bd, $sql); //-- Traitement ------------------------------------- $enr = mysqli_fetch_row($r); echo 'Il y a ', $enr[0], ' livres dans notre base'; // Libération de la mémoire associé au résultat de la requête mysqli_free_result($r); //-- Déconnexion ------------------------------------ mysqli_close($bd); htmlFin(); ?>