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)

1.1 La partie HTML
1.2 La partie Javascript

2. La page PHP / MySQL

3. 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>

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>

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 ;
?>

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 */;