Présentation d’une requête AJAX (Javascript - PHP - MySQL)
LES requêtes AJAX sont des scripts écrits en Javascript servant à envoyer et recevoir des données à partir une page statique (HTML), le plus souvent par l’intermédiaire d’un script (par exemple PHP) interrogeant une base de données (par exemple SQL). Elles permettent d’éviter au navigateur de recharger toute une page lorsqu’un événement permet une légère modification de la page (complétion d’un champ, filtre parmi des mots…).
Avril 2020
1. La page appelante (HTML / javascript) |
2. La page PHP / MySQL3. Le fichier MySQL à importer par le serveur |
L’exemple utilisé permet de proposer des noms appartenant à une base de données selon les premières lettres saisies dans un champ (effet filtre).
1. La page appelante (HTML / javascript)
Voici le fichier qui travaille du côté client, il s’agit d’une page HTML contenant du javascript, affichée par un navigateur. Soit elle est sur un site distant, soit appelée sur un poste de travail muni d’un système LAMP (Linux - Apache - MySQL - PHP), WAMP pour Windows ou MAMP pour Mac OSX. Sur Linux, la barre d’URL doit commencer par localhost/.
<!DOCTYPE html> <html lang="fr"><head> <meta charset="utf-8"> <title>Exemple fonctionnel de requête AJAX, avec Javascript, PHP et MySQL</title> <script> function frappe() { var nom =document.getElementById("ami").value ; if (!nom) { nom =document.getElementById("prop").innerHTML=""; return ; } +var chaine ="nom=" +nom +"&nr=" +nom ; var quete =new XMLHttpRequest() ; quete.open("POST", "amis.php", true) ; quete.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") ; quete.send(chaine) ; quete.onreadystatechange =fournir ; function fournir() { if (quete.readyState ==4 && quete.status ==200) { document.getElementById("prop").innerHTML =quete.responseText ; } } } </script> </head><body> <h3>Choisir une connaissance</h3> <form action="envoyer.php" method="post"> <input id="ami" size="4" onKeyUp="frappe()"> <input type="submit" value="Envoyer"> <select id="prop"></select> </form> </body></html>
1.1 La partie HTML
Cette partie, écrite en HTML, sert à recevoir un ou plusieurs caractères, envoyé(s) vers une fonction javascript.
<form action="envoyer.php" method="post"> <input type="submit" value="Envoyer"> <input id="ami" name="ami" size="4" onKeyUp="frappe()"> <select id="prop"></select> </form>
- les deux premières lignes serviront en fin de processus, lorsqu’un nom aura été choisi. La page envoyer.php devra avoir été écrite (ici en PHP), le bouton Envoyer déclenchant l’action
- la troisième ligne prévoit un champ identifié ami pour frapper une lettre. La fonction frappe() sera déclenchée lors que la touche est relâchée (événement onKeyUp)
- La balise select, identifiée par prop sera recevra des données issues de la requête AJAX
1.2 La partie Javascript
C’est la partie la plus complexe, écrite en javascript (présentation succincte du langage sur cette page).
<script> function frappe() { var nom =document.getElementById("ami").value ; if (!nom) { nom =document.getElementById("prop").innerHTML=""; return ; } var chaine ="nom=" +nom +"&nr=" +nom ; var quete =new XMLHttpRequest() ; quete.open("POST", "amis.php", true) ; quete.setRequestHeader("Content-Type", "application/x-www-form-urlencoded") ; quete.send(chaine) ; quete.onreadystatechange =fournir ; function fournir() { if (quete.readyState ==4 && quete.status ==200) { document.getElementById("prop").innerHTML =quete.responseText ; } } } </script>
- la ligne var nom =… récupère la valeur de la balise identifiée par ami
- la deuxième, moins nécessaire, sera explicitée par la suite
- la troisième fabrique la chaîne de requête à passer par POST au fichier, qui se compose de variables associées à des valeurs: var1=val1&var2=val2&etc…
- la quatrième initialise la variable quete et permet d’indiquer le fichier-cible php et le mode de passage de données. true désigne le mode asynchrone: le navigateur n’attend pas le retour de données pour continuer son travail d’affichage.
- la sixième envoie la chaîne à la page PHP et déclenche la fonction fournir, à écrire sans ()
- la fonction fournir() attribue à la balise identifiée par prop la réponse à la requête envoyée au fichier PHP.
- la condition n’est vraie que si le processus est terminé (quete.readyState ==4) et qu’une page a été trouvée (quete.status ==200, variante heureuse du célébrissime 'error 404')
Note: la deuxième ligne sert à vider le contenu de la balise <select> si le champ est vide après effacement des caractères de la balise input identifiée par ami
2. La page PHP / MySQL
La page qui travaille du côté serveur est tout ce qu’il y a de plus classique en PHP / MySQLi. Dans cet exemple, elle s’appelle amis.php.
<?php $con =mysqli_connect("monServeur", "monId", "monPasse", "maBase") ; $nom =$_POST["nom"] ; $nr =$_POST["nr"] ; $requete ="SELECT nr, nom FROM amis WHERE nom LIKE "$nom%" OR nr LIKE "$nr%" ORDER BY nom" ; $yeap =mysqli_query($con, $requete) ; $chaine="" ; while($rang=mysqli_fetch_array($yeap)) { $chaine .="<option>".$rang["nr"]." - ".$rang["nom"] ; } echo $chaine ; ?>
- première ligne: connexion à la base de données
- deuxième ligne: récupération des données façon POST selon la chaîne variable=valeur passées par le fichier appelant amis.html
- troisième ligne: requête MySQL: la même valeur est appliquée aux champs nom ou nr: il est permis de rechercher les amis par nom ou par identifiant
- quatrième ligne: passage de la requête au serveur MySQL (ou MariaDB) et initialisation de la chaîne qui sera renvoyée
- boucle while: concaténation de chaînes identifiant + nom des personnes correspondant à la recherche dans des sous-balises <option>
- dernière ligne: écriture, ce qui équivaut à l’envoi des données vers la page appelante.
3. Le fichier MySQL à importer par le serveur
Importer ces données en PHPmyAdmin est très intuitif (il n’est pas nécessaire de changer le nom de l’hôte localhost ni le nom de la base de données `maBase`. Pour éviter les problèmes d’encodage, aucun accent n’a été utilisé dans les données. Chaque lettre de l’alphabet commence au moins un des noms.
-- phpMyAdmin SQL Dump -- version 5.0.1 -- https://www.phpmyadmin.net/ -- -- Hôte : localhost -- Généré le : lun. 01 avr. 2020 à 01:04 -- Version du serveur : 10.3.22-MariaDB-0+deb10u1 -- Version de PHP : 7.3.14-1~deb10u1 SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET AUTOCOMMIT = 0; START TRANSACTION; SET time_zone = "+00:00"; /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8mb4 */; -- -- Base de données : `maBase` -- -- -------------------------------------------------------- -- -- Structure de la table `amis` -- CREATE TABLE `amis` ( `nr` tinyint(4) UNSIGNED NOT NULL, `nom` varchar(20) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; -- -- Déchargement des données de la table `amis` -- INSERT INTO `amis` (`nr`, `nom`) VALUES (1, 'Claire'), (2, 'Bernard'), (3, 'Isabelle'), (4, 'Daniel'), (5, 'Annie'), (6, 'Nicolas'), (7, 'Ginette'), (8, 'Hubert'), (9, 'Anne'), (10, 'Antoine'), (11, 'Karen'), (12, 'Lionel'), (13, 'Marie'), (14, 'Nathalie'), (15, 'Odile'), (16, 'Philippe'), (17, 'Quentin'), (18, 'Raoul'), (19, 'Sophie'), (20, 'Thierry'), (21, 'Ursule'), (22, 'Robert'), (23, 'Guy'), (24, 'Xavier'), (25, 'Yves'), (26, 'Yoko'), (27, 'Lily'), (28, 'Milan'), (29, 'Fanny'), (30, 'Michel'), (31, 'Willy'), (32, 'Ella'), (33, 'Viviane'), (34, 'Zelda'), (35, 'Jane'), (36, 'Jean'); -- -- Index pour les tables déchargées -- -- -- Index pour la table `amis` -- ALTER TABLE `amis` ADD PRIMARY KEY (`nr`); -- -- AUTO_INCREMENT pour les tables déchargées -- -- -- AUTO_INCREMENT pour la table `amis` -- ALTER TABLE `amis` MODIFY `nr` tinyint(4) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=37; COMMIT; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;