Veuillez noter que je publie maintenant mes articles sur Apical, votre plateforme d'apprentissage.

mysqli : la nouvelle technique pour travailler avec une base de données MySQL

Attention
Vous trouverez une version plus à jour de cet article sur Apical, votre plateforme d'apprentissage :
https://apical.xyz/fiches/travailler_avec_les_donnees_002/Branchement_a_une_base_de_donnees

Apical, ma plateforme d'apprentissage

Votre site Web devra fort probablement accéder à une base de données pour définir soit sa structure (ex : ses menus, ses configurations), soit son contenu (ex : le texte à afficher dans les pages Web, les usagers ayant droit de se connecter), soit les deux.

Il existe plusieurs techniques pour accéder à la base de données et y exécuter des requêtes. Avant PHP 5.5.0, plusieurs programmeurs utilisaient mysql_connect() et les autres fonctions de l'extension mysql (voir l'article « Travailler avec une base de données MySQL »).

Cette extensions est désormais obsolète. Les programmeurs avisés utilisent maintenant l'extension mysqli. Le i tient pour improved. Il s'agit donc d'une version améliorée de l'extension originale.

▼Publicité

Branchement à la base de données

Depuis PHP 5.5.0, les programmeurs PHP doivent utiliser la classe mysqli pour se brancher à la base de données.

Syntaxe PHP

$mysqli = new mysqli("addresse_serveur_mysql", "usager_mysql", "mot_de_passe", "base_de_donnees");

...   // attention : ce code est incomplet. Voir plus bas...

$mysqli->close();

Sur un site en développement, la connexion se fera comme suit :

PHP

$mysqli = new mysqli("localhost", "root", "", "garage");

...

$mysqli->close();

Si vous travaillez sur un site en ligne, la commande aura plutôt cette forme :

PHP

$mysqli = new mysqli("nomdomaine.com", "toto", "tata", "garage");

...

$mysqli->close();

Dans ce dernier exemple, l'usager toto serait un usager MySQL ayant des droits restreints. Ceci permet de limiter les dégâts en cas où un trou de sécurité serait découvert.

Refermer la connexion

Dans les extraits de code précédents, vous avez sans doute remarqué l'utilisation de $mysqli->close(). Cette méthode s'occupe de refermer la connexion afin de libérer les ressources le plus tôt possible. Si vous l'omettez, la connexion sera automatiquement refermée lorsque l'internaute refermera le site Web.

À ce sujet, deux options s'offrent à vous :

  • Vous ouvrez la connexion au début du programme et la refermez à la fin. Par exemple, la connexion pourrait avoir lieu dans entete.inc et elle sera refermée dans piedpage.inc.
  • Vous ouvrez la connexion avant chaque requête et vous la refermez tout de suite après­.

Notation objet vs notation procédurale

Dans les exemples précédents, la variable $mysqli est un objet dont la classe est mysqli. Pour accéder aux membres de cet objet, on le fera suivre d'une flèche puis du nom du membre.

Ex :

Notation objet (PHP)

$mysqli = new mysqli("localhost", "root", "", "garage");

...

$resultat = $mysqli->query(...);

echo "La requête a retourné $mysqli->affected_rows enregistrements";

...

$mysqli->close();

Il aurait également été possible d'utiliser la notation procédurale :

Ex :

Notation procédurale (PHP)

$mysqli = mysqli_connect("localhost", "root", "", "garage");

...

$resultat = mysqli_query($mysqli, ...);

echo "La requête a retourné " , mysqli_num_rows($resultat) . " enregistrements";

...

mysqli_close($mysqli);

Vérifier si la connexion a fonctionné

Il peut y avoir une foule de raisons qui empêchent une connexion, comme par exemple :

  • Serveur non disponible (problème de réseau, service arrêté, problème physique sur la machine, etc.)
  • Mauvais nom de base de données ou base de données effacée
  • Usager MySQL inexistant ou n'ayant pas les droits suffisants
  • Mauvais mot de passe
  • etc.

C'est pourquoi il importe de toujours vérifier si la connexion a fonctionné avant de poursuivre le traitement. 

Si vous omettez cette vérification, le site Web affichera, dans le haut de l'écran, un message du genre :

Warning: mysqli::mysqli(): (HY000/1049): Unknown database 'garage'

Ex :

Erreur de connexion

Voici donc la syntaxe à utiliser pour éviter cet affichage non désiré :

Syntaxe PHP

@$mysqli = new mysqli("addresse_serveur_mysql", "usager_mysql", "mot_de_passe", "base_de_donnees");

if ($mysqli->connect_errno) {

    die("Échec lors de la connexion à la base de données");

}

...   

$mysqli->close();

Ex :

PHP

@$mysqli = new mysqli("localhost", "root", "", "garage");

if ($mysqli->connect_errno) {

    die("Échec lors de la connexion à la base de données");

}

À remarquer :

  • L'ajout du @ devant l'appel de mysqli assure qu'en cas de problème, cette instruction ne générera pas l'affichage d'un message d'erreur. 
  • Si un erreur est détectée, son code sera enregistré dans $mysqli->errno. Cette variable sera donc différente de 0, ce qui est évalué comme un vrai. Donc, le code présent dans le if sera exécuté.
  • La fonction die() affiche un message à l'écran puis termine l'exécution du programme. Son utilisation est correcte dans le contexte actuel. Cependant, il faut limiter l'utilisation de die() ailleurs dans le programme car dans la plupart des cas, on pourra utiliser une technique plus élégante.
  • Dans le die(), on prend soin d'encoder les accents car le die() survient avant l'instruction qui indique au navigateur le format d'encodage utilisé.

Lire les résultats de la requête MySQL

Le résultat de la requête est un tableau à deux dimensions. Chaque ligne du tableau représente un enregistrement répondant à la condition de la requête et chaque colonne du tableau représente un champ extrait. Selon les données que vous avez entrées dans la table client, le résultat de la requête pour trouver les clients de Victoriaville pourrait être le suivant :

1 Jacynthe Courtois
2 Marc Frenette
4 Axelle Demers
8 Line Jacques

Requête qui retourne une série d'enregistrements

Afin de pouvoir utiliser le résultat de la requête, il faut extraire les lignes du tableau à l'aide de fetch_row() ou fetch_assoc(). Chaque enregistrement sera un tableau à une dimension (vecteur) et chaque champ correspondra à un élément du tableau.

Si vous utilisez  fetch_row(), vous devrez utiliser un indice pour obtenir le champ désiré. Le premier champ mentionné dans la requête sera $enreg[0], le second champ sera $enreg[1], etc.

Ex :

PHP

$requete = "SELECT client_id, client_prenom, client_nomfamille FROM client ORDER BY client_nomfamille, client_prenom";

$resultat = $mysqli->query($requete);     // exécute la requête

if ($resultat) {    // si la requête a fonctionné

   if ($mysqli->affected_rows != 0) {    // si la requête a retourné au moins un enregistrement

      echo "<ul>";

      while ($enreg = $resultat->fetch_row()) {     // extrait chaque ligne une à une

         echo "<li>$enreg[0] - $enreg[1] $enreg[2]</li>";      // affichera l'identifiant, le prénom et le nom de famille de chaque client

      }

      echo "</ul>";

   } 

   else {

      echo "Il n'y a aucun client dans le système.";

   }

}

else {

   echo "Nous sommes désolés, les données ne peuvent pas être affichées.";

}

Pour mieux décoder ce qui vient de se passer, rappelez-vous que :

  • Chaque itération de la boucle place une ligne du tableau dans le vecteur $enreg
  • Le premier champ de la requête étant client_id, nous pouvons retrouver l'identifiant du client en utilisant $enreg[0]
  • Le second champ étant le nom, on utilisera $enreg[1] pour le retrouver.
  • etc.

Requête qui retourne un seul enregistrement

Parfois, on recherchera un seul enregistrement dans une table. La logique utilisée pourra ressembler à celle-ci. Attention : puisque la requête contient une variable PHP, il serait préférable d'utiliser la technique des requêtes préparées pour protéger la base de données contre les pirates.

PHP

$requete = "SELECT client_prenom, client_nomfamille FROM client WHERE client_id='$id'";

$resultat = $mysqli->query($requete);     // exécute la requête

if ($resultat) {    // si la requête a fonctionné

   if ($mysqli->affected_rows != 0) {    // si la requête a retourné au moins un enregistrement

      $enreg = $resultat->fetch_row();  // la seule ligne du tableau sera maintenant accessible 

      echo "<p>$enreg[0] $enreg[1]</p>";      // affichera le prénom et le nom de famille du client demandé

   } 

   else {

      echo "Il est impossible de retrouver les données du client.";

   }

}

else {

   echo "Nous sommes désolés, les données ne peuvent pas être affichées.";

}

À remarquer :

  • Il est inutile d'effectuer une boucle si on ne cherchait à retrouver qu'un seul enregistrement. 
  • Le tableau des résultats, même s'il ne contient qu'une seule ligne, est un tableau à deux dimensions. Il ne peut pas être accessible directement. 
  • On extraira sa seule ligne avec $resultat->fetch_row().

fetch_assoc()

Si vous préférez travailler avec le nom des champs plutôt qu'un indice représentant leur position dans la requête, fetch_assoc() sera votre ami.

Voici un second exemple utilisant cette fois fetch_assoc().

Remarquez l'utilisation des accolades pour forcer l'interprétation de « $enreg['client'] » avant de l'inclure dans la chaîne de caractères.

Ex :

PHP

while ($enreg = $resultat->fetch_assoc()) {

   echo "<li>{$enreg['client_id']} - {$enreg['client_prenom']} {$enreg['client_nomfamille']}</li>";  

}

Pour plus d'information

« Connexions ». PHP. http://www.php.net/manual/fr/mysqli.quickstart.connections.php

« Extension mysqli ». PHP. http://php.net/manual/fr/book.mysqli.php

« Choisir une API ». PHP. http://www.php.net/manual/fr/mysqlinfo.api.choosing.php

« Interface procédurale et orientée objet ». PHP. http://php.net/manual/fr/mysqli.quickstart.dual-interface.php

Catégories

9 commentaires