Créer des sites Web dynamiques en PHP (PHP Hypertext Preprocessor)

Auteur: Mohamed CHINY Durée necessaire pour le cours de Créer des sites Web dynamiques en PHP (PHP Hypertext Preprocessor) Niveau recommandé pour le cours de Créer des sites Web dynamiques en PHP (PHP Hypertext Preprocessor) Supports vidéo non disponibles pour ce cours Exercices de renforcement disponibles pour ce cours Quiz disponible pour ce cours

Page 22: Connexion à une base de données MySQL en PHP (Extension MySQLi)

Toutes les pages
Notez que cette partie du cours de PHP est traitée à titre indicatif, car elle explique comment se servir de l'extension MySQLi. Bien que cette extension fonctionne correctement sur les nouvelles versions de PHP (PHP7 et sous-versions ultérieures), l'objet PDO (PHP Data Objects), détaillé dans le cours de POO en PHP, constitue la meilleure solution pour communiquer avec les bases de données en PHP. Il est donc vivement conseillé de travailler avec l'objet PDO plutôt qu'avec l'extension MySQLi.

Site Web dynamique

Pages Web dynamiques dont le contenu change indirectement

Un site Web dynamique est un site Web dont le contenu change automatiquement. Autrement dit, le contenu visible sur la page n'est pas toujours intégré directement en HTML par le Webmaster, mais peut être généré à la volée suite à des conditions particulières comme l'historique de navigation, la localisation géographique du visiteur, les privilèges accordés à celui-ci... Cependant, le contenu des sites web dynamiques provient souvent de sources de données. Ces sources peuvent être des fichiers texte, fichiers XML, sources Json, et par dessous tout, il y a les bases de données.

En effet, les bases de données constituent les sources de données les plus populaires pour différentes raisons. J'en cite:
  • Les bases de données (dites relationnelles) sont structurées sous formes de tables. Chacune des tables contient des données jugées cohérentes, mais complémentées par les données qui figurent dans d'autres tables via des relations.
  • Les bases de données sont faciles à parcourir et interroger, et c'est principalement grace au langage de requêtes SQL (Structured Query Language).

Bases de données et PHP

PHP est connu pour sa capacité à intéragir aisément avec les bases de données. J'entends par les bases de données pratiquement tous les SGBD (Systèmes de Gestion de Bases de Données) populaires (MySQL, PostgreSQL, MariaDB, Oracle, MSSQL...). Cependant, le SGBD MySQL reste le plus largement utilisé avec PHP.

Afin d'intéragir avec une base de données MySQL, PHP propose trois méthodes différentes:
  • Extension MySQL originale: Il s'agit de l'extension MySQL native au PHP. Pendant longtemps elle a été pratiquement la seule extension disponible, mais elle est rendue obsolète depuis la version 5.5 de PHP, et a été supprimée en PHP7.
  • Extension MySQLi: Il s'agit d'une extension un peu plus moderne. C'est d'ailleurs cette extension que l'on va traiter dans cette section.
  • Objet PDO (PHP Data Objects): L'objet PDO constitue de loin la meilleure solution pour intéragir avec une base de données en PHP. Elle dispose de plusieurs avantages, et le plus marquant c'est qu'il permet l'abstraction de la base de données, ce qui a pour effet de pouvoir communiquer avec de nombreux SGBD (et pas que MySQL) tout en maintenat le même code PHP. L'objet PDO est traité dans cette page.

Extension MySQLi

Pré-requis pour coder en PHP/MySQL

Il est évident que pour éditer du code PHP qui peut communiquer avec une base de données (en l'occurence MySQL), il faut être à l'aise avec le langage de requêtes SQL (Structured Query Language).

SQL est un langage qui permet de communiquer avec les bases de données (dites bases de données SQL). Il s'agit d'un langage très riche en fonctionnalités qui permettent de mener des opérations plus ou moins complexes sur les bases de données. Cependant, dans cette section on va se contenter des requêtes CRUD (Create, Read, Update, Delete) qui constituent les requêtes les plus utilisées pour créer un site Web dynamique ou application Web.
Si vous n'êtes pas initié au langage SQL, vous n'avez pas à vous inquiéter car on va voir que 4 requêtes du CRUD qui sont faciles à retenir (et adapter selon vos besoins). Sinon je vous recommande vivement de découvrir des opérations plus avancées comme les jointures ou les requêtes imbriquées en vous rendant sur le site support de SQL https://sql.sh/.

Prise en charge de l'extension MySQLi

L'extension MySQLi est prise en charge nativement en PHP. Sa déclaration est faite de manière automatique dans le fichier php.ini dans le bloc consacré aux extensions de la manière suivante:
extension=php_mysqli.dll
Donc, aucune configuration spéciale n'est requise pour de s'en servir.

Opérations CRUD à l'aide de MySQLi

Création de la base de données

Afin de créer la base de données sur le serveur, ainsi que les tables et aussi créer les utilisateurs en leur accordant les privilèges nécessaires, il est préférable de se servir de l'outil PHPMyAdmin qui propose une interface graphique pour gérer les bases de données MySQL. Cependant, ces opérations peuvent être faites sur la ligne de commande si vous êtes à l'aise avec le langage SQL.

Dans notre cas, on va supposer que l'on va créer une base de données du nom de mabase et l'utilisateur root avec le mot de passe root.
Figurez vous qu'il s'agit d'un exemple d'utilisation de l'extension MySQLi. Autrement dit, s'il s'agit d'un vrai projet Web, alors il faut songer à créer un utilisateur avec des privilèges restreints et lui appliquer un mot de passe plus consistant pour des raisons évidentes de sécurité.
Dans notre base de données on va créer une table du nom de personnes dont le code SQL est le suivant:
CREATE TABLE `personnes` (
   `id` int(10) unsigned NOT NULL auto_increment,
   `date` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
   `nom` varchar(40) NOT NULL,
   `prenom` varchar(40) NOT NULL,
   `login` varchar(40) NOT NULL,
   `pass` varchar(40) NOT NULL,
   PRIMARY KEY (`id`)
);

Connexion au serveur et sélection d'une base de données

La première opération à faire si on veut interroger une base de données c'est la connexion au serveur qui héberge celle-ci à l'aide du code suivant:
$id=mysqli_connect("localhost","root","root");
La fonction mysqli_connect() permet de connecter le serveur de base de données avec l'utilisateur root qui a le mot de passe root (respectivement deuxième et troisième arguments). Dans notre cas, le serveur de base de données et le serveur local localhost (premier argument).

La fonction mysqli_connect() retourne un identifiant de connexion ($id dans notre cas) ou la valeur booléenne false en cas d'échec.

Une fois la connexion au serveur établie, on peut désormais sélectionner la base de données à interroger via le code suivant:
mysqli_select_db($id,"mabase");
La fonction mysqli_select_db() retourne un resultat booléen (true en cas de succès et false en cas d'échec) et accépte deux arguments qui sont respectivement l'identifiant de la connexion au serveur et le nom de la base de données.

Cependant, on peut résumer les deux opérations que l'on vient de voir dans une seule instruction de la manière suivante:
$id=mysqli_connect("localhost","root","root","mabase");
En effet, la fonction mysqli_connect() peut accépter un quatrième argument qui représente le nom de la base de données.

Imagniez maintenant qu'une erreur survient (serveur de base de données à l'arrêt, erreur de login ou de mot de passe...) dans ce cas la fonction mysqli_connect() retournera false, mais elle générera aussi une erreur PHP de type E_WARNING. Un message peut s'afficher ou non sur le navigateur selon votre configuration. Mais comme vous le savez, ces types d'erreur n'empêchent pas l'exécution du reste du code. Or, les instructions qui vont suivre dépendront probablement du succès de la connexion, autrement dit, des erreurs supplémentaires vont survenir.

Afin d'empêcher cette avalanche d'erreurs, il serait mieux d'arrêter prématurément le script PHP suite à l'erreur de connexion. On va donc utiliser le code suivant:
$id=mysqli_connect("localhost","root","root","mabase") or die("Erreur de connexion");
Dans ce cas, si une erreur survient suite à une mauvaise connexion, la fonction die(), qui va appliquer un arrêt prématuré du script PHP, est exécuté en affichant le message Erreur de connexion.

Execution des opérations CRUD

Afin d'exécuter une requête SQL via un script PHP on fait appel à la fonction mysqli_query(). Par exemple, si on veut insérer un nouvel enregistement dans la table personnes on va exécuter le code suivant:
$req=mysqli_query($id,"insert into personnes (nom,prenom,login,pass) values('Einstein','Albert','a.einstein',md5('2020')");
La fonction mysqli_query() accepte deux arguments qui sont, respectivement, l'identifiant de la connexion précédemment établie et la requête SQL à exécuter.

La fonction mysqli_query() retourne un identifiant de connexion ($req dans notre cas) ou false en cas d'échec.

Si on veut modifier l'enregistrement que l'on vient d'insérer (on va changer le mot de passe par exemple) alors on va exécuter l'instruction suivante:
$req=mysqli_query($id,"update personnes set pass=md5('ABCD') where id=1");
Bien entendu, on a supposé que le champ id associé à cet enregistrement vaut 1.

Si maintenant on veut supprimer cet enregistrement alors on exécute le code PHP suivant:
$req=mysqli_query($id,"delete from personnes where id=1");
Figurez vous que l'identifiant $req ne nous a été d'aucune utilité pour les trois requêtes exécutées. Donc on peut ne pas le déclarer.

Exécution de la requête de sélection

Bien que la sélection fait aussi partie des opéraitons CRUD, elle demande quand même un peu plus de traitement. Alors, supporsons que l'on veut afficher les noms et prénoms de tous les enregistrements qui figurent dans la table personnes (s'il y'en a). Dans ce cas on exécute les instructions suivantes:
$req=mysqli_query($id,"select nom,prenom from personnes");
while($tab=mysqli_fetch_assoc($req)){
   echo $tab["nom"]." ".$tab["prenom"];
}
Une fois la reqûete de sélection exécutée, on prévoit la boucle while qui sera exécutée autant de fois qu'il y a des enregistrements dans la table.

La fonction mysqli_fetch_assoc() qui accepte comme argument l'identifiant de la requête ($req) retourne l'enregistrement courant sous forme d'un tableau PHP ($tab), ou false s'il n'y a plus aucun enregistrement, ce qui a pour effet d'interrompre la boucle while.

Le tableau PHP $tab contient autant d'indexes que de champs sélectionnés. Dans ce cas, il contient deux indexes qui correspondent respectivement au nom et au prénom.
Notez que la fonction mysqli_fetch_assoc() retourne un tableau associatif dont les clés correspondent aux attributs de la table (dans notre cas il s'agit des clés nom et prenom.
Si on veut connaitre le nombre de résultats retournés par la requête de sélection on fait appel à la fonction mysqli_num_rows() comme ceci:
$nbr_resultats=mysqli_num_rows($req);

Conclusion

A la fin, je vous rappelle que cette section est traitée à titre indicatif. Et comme je l'ai mentionné plus haut, il est conseillé d'utiliser l'objet PDO (PHP Data Objects) pour interroger les bases de données plutôt que l'extension MySQLi.

Je vous invite à consulter le cours consacré à l'objet PDO en suivant ce lien.