formateur informatique

Relier des listes déroulantes en cascade en PHP

Accueil  >  Technique  >  Php  >  Php Avancé  >  Relier des listes déroulantes en cascade en PHP
Livres à télécharger


Pour partager cette vidéo sur les réseaux sociaux ou sur un site, voici son url :


Inscription Newsletter    Abonner à Youtube    Vidéos astuces Instagram
Sujets que vous pourriez aussi aimer :


Listes déroulantes reliées en PHP

Dans cette formation Php, nous souhaitons aboutir le développement des listes déroulantes en cascade. Nous avions apporté la solution par le code client Javascript. La seconde liste déroulante attend le choix émis au travers de la première, pour se remplir en conséquence. Aujourd'hui, nous souhaitons que l'offre réagisse en fonction des mises à jour en base de données. Si de nouveaux éléments sont insérés, ils doivent être dynamiquement proposés par ces listes reliées entre elles. Dans la formation Javascript, nous n'avions pu que simuler ce principe. Le code client ne peut pas attaquer les bases de données.

Sources et présentation de la problématique
Avant de débuter, il est donc nécessaire de récupérer les travaux précédents ainsi que les informations de base de données. La décompression fournit le fichier de la page Web principale à la racine. Il est nommé index.php. Il est accompagné de ses ressources externes dans les sous dossiers. Nous y reviendrons en temps voulu.

Comme nous l'avait enseigné la formation pour débuter la programmation en Php, ce projet doit être référencé dans EasyPhp. Un nom doit lui être attribué et l'adresse issue de l'explorateur Windows doit être renseignée. Bien sûr les deux serveur, Http et Database, doivent être démarrés.

Ajouter projet Php des listes déroulantes reliées dans EasyPhp

Dès lors, l'application serveur apparaît dans la liste des projets émulés par EasyPhp.
  • Cliquer sur son lien pour accéder à sa page d'accueil,
Une liste déroulante se propose en haut de la page Web, au-dessus des deux calques destinés à la restitution des informations.
  • Cliquer sur cette liste déroulante pour déployer son contenu,
Vous accédez ainsi à l'énumération de quelques départements. Notre source de données archive en effet des idées de sorties.
  • Cliquer sur l'un des départements pour émettre un choix,
Aussitôt, une image miniature représentant la zone géographique, se charge dans le cadre de droite. Et dans le même temps, une seconde liste déroulante apparaît. Cette dernière est bien entendu reliée à la première. Elle ne propose que les villes appartenant au département sélectionné. Si vous changez de département dans la première liste déroulante, le contenu des villes dans la seconde s'adapte automatiquement.

Liste déroulante Html remplie en fonction du choix dans la première liste déroulante

En revanche, si vous validez un choix de ville à l'aide de la seconde liste déroulante, vous constatez que la page est réinitialisée. Un PostBack est effectivement généré pour transmettre ces données au serveur. Et comme nous l'avions appris, un PostBack est un aller-retour vers le serveur. En conséquence, il recharge intégralement la page Web.

Nous pallierons ce défaut dans une prochaine formation grâce à des techniques de programmation Ajax. Nous traiterons les données réceptionnées sur le serveur à l'aide d'une page externe qui restituera son traitement en lieu et place. De fait, nous conservons l'affichage que nous avions défini.

Nous proposons désormais de constater les imbrications de code ayant conduit à ce résultat. En effet, il va s'agir dans cette formation de remplir dynamiquement ces listes déroulantes, en fonction des potentielles mises à jour de la base de données.
  • A la racine du dossier de décompression, cliquer droit sur le fichier index.php,
  • Dans le menu contextuel, choisir de l'ouvrir avec un éditeur tel que le Notepad++,
Entre les lignes 46 et 61 pour un éditeur Notepad, vous notez la présence du formulaire Html avec sa méthode Post, appelant la page index.php elle-même. La première liste déroulante est nommée choix_dep. Elle est remplie de façon statique. Nous devrons pallier cette méthode pour l'implémenter en fonction des données issues de la base de données. La seconde liste déroulante n'existe pas encore. Un choix de département dans la première liste déroulante appelle la fonction Javascript charger_villes. Cette dernière est écrite à partir de la ligne 92 pour un éditeur Notepad. Elle questionne la fonction retour_villes d'un script externe situé dans le sous dossier js. C'est en fonction des valeurs qu'elle retourne, les villes correspondant au département choisi, qu'elle construit à la volée cette seconde liste déroulante.
  • A la racine du dossier de décompression, double cliquer sur le sous dossier js pour l'ouvrir,
  • Puis, cliquer droit sur le fichier villes_dep.js,
  • Dans le menu contextuel, choisir de l'ouvrir avec un éditeur comme le Notepad,
Vous y notez effectivement la présence de la fonction retour_villes :

function retour_villes(le_dep)
{
var chaine_villes="";

switch(le_dep)
{
case "07":
chaine_villes = "Alba la Romaine|Annonay ...";
break;
case "26":
chaine_villes = "Bourg de Péage|Bourg lès Valence| ...";
break;
case "38":
chaine_villes = "Bourgoin Jallieu|Chamrousse|Echirolles| ...";
break;
case "69":
chaine_villes = "Condrieu|Ecully| ...";
break;
case "73":
chaine_villes = "Chambéry|Le bourget du lac| ...";
break;
}

return chaine_villes;
}


Cette fonction attend le numéro du département correspondant au choix de l'internaute émis depuis la liste déroulante. En fonction de ce numéro, elle retourne dans une chaîne de texte, toutes les villes liées. C'est ainsi qu'elles sont réceptionnées par le code Javascript pour construire et remplir la seconde liste déroulante en cascade.

Désormais, ces informations doivent devenir dynamiques. Les villes peuvent évoluer et s'enrichir mais les départements aussi. Nous proposons donc de questionner la base de données et de récréer ce script à la volée. Nous savons créer et écrire dans des fichiers, comme nous l'avons appris au travers de formations Php. Ainsi, à chaque choix de l'internaute dans la première liste déroulante, le contenu de la seconde s'adaptera sans solliciter le serveur. Nous gardons à l'esprit l'importance de bien équilibrer les charges pour les sites Web jouissant d'un fort trafic.

Importer les données en base MySql
Pour atteindre l'objectif de cette formation, nous devons disposer de données. Elles sont proposées au format SQL dans le sous dossier bdd du dossier de décompression. Il s'agit de remplir la table liste_id de la base de données ids que nous avions créée au travers de la formation Php pour importer des données en base MySql. Si cette table et cette base de données n'existent pas, vous devez vous y référer pour les créer.
  • Depuis l'interface d'EasyPhp, cliquer sur le bouton Open du module MySql Administration,
  • Dans le volet gauche de PhpMyAdmin, cliquer sur le lien de la base de données ids,
  • Puis, en haut de la fenêtre, cliquer sur l'onglet Importer,
  • Cliquer alors sur le bouton Parcourir pour désigner le fichier d'importation,
  • Dans le sous dossier bdd, double cliquer sur le fichier debut_id.sql,
  • Conserver tous les autres choix par défaut et cliquer sur le bouton Exécuter en bas de page,
Données externes importées en base MySql pour remplir dynamiquement les listes déroulantes à relier en Php

Un message de confirmation apparaît à l'issue du traitement.
  • Dans le volet de gauche, cliquer sur la table liste_id de la base de données ids,
Nous accédons ainsi au contenu de la table et pouvons consulter les données importées. Cette dernière propose désormais 1046 enregistrements. Les départements sont listés dans le champ liste_dep tandis que les villes sont archivées dans le champ liste_ville.

Pour charger dynamiquement les listes déroulantes sur la page Web, le code Php doit accéder aux données de cette base MySql. Et pour cela, le compte utilisateur que nous avions défini dans la formation pour accéder aux fichiers externes, doit être créé s'il n'existe pas :
  • Nom d'utilisateur : codePHP,
  • Mot de passe : php123bd,
  • Nom d'hôte : Votre adresse locale attribuée par EasyPhp, ici : 127.0.0.1,
Vous devez définir les droits administrateurs en cochant la case Tout cocher.

Connecter la base de données MySql
Pour reconstruire le script Javascript de façon dynamique, donc par le code Php, nous devons commencer par récupérer la liste de chaque département. Et pour chacun d'eux, nous devons extraire toutes les villes qu'ils comportent sans doublons. Nous devons donc exécuter une requête SQL avec une clause DISTINCT sur la base de données ids. Pour exécuter une requête sur la base de données, nous devons commencer par établir la connexion à cette dernière. Il s'agit simplement de reconstruire la chaîne de connexion, avec les identifiants, en entête de code.
  • Revenir dans le code de la page index.php,
  • En entête, juste avant la déclarative Html, ajouter la section Php suivante :
<?php
$liaison = mysqli_connect("127.0.0.1", "codePHP", "php123bd");
mysqli_select_db($liaison, "ids");
?>

<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
...


Nous créons la chaîne de connexion habituelle, mémorisée sous le nom de variable $liaison, grâce à la fonction Php mysqli_connect. Pour cela, nous lui passons les paramètres du nom d'hôte, du nom d'utilisateur et de son mot de passe associé. C'est alors la fonction Php mysqli_select_db qui établit la liaison selon cette chaîne de connexion en premier paramètre et le nom de la base de données en second.

Souvenez-vous, toute connexion ouverte doit être fermée à l'issue des traitements.
  • En toute fin de code, après la balise Html fermante, ajouter la section Php suivante :
...
</script>
</html>
<?php
mysqli_close($liaison);
?>


Comme nous en avons l'habitude désormais, nous exploitons la fonction Php mysqli_close, avec la chaîne de connexion en paramètre, pour libérer les ressources.

Si vous rechargez la page d'accueil et qu'aucune erreur n'est générée, cela signifie que la liaison est correctement établie.

Ecrire un code Javascript en PHP
Désormais, nous allons pouvoir attaquer la base de données pour en extraire la substance.
  • En entête de code, après l'établissement de la connexion, ajouter les instructions Php suivantes :
<?php
$liaison = mysqli_connect("127.0.0.1", "codePHP", "php123bd");
mysqli_select_db($liaison, "ids");

$requete = "SELECT DISTINCT liste_ville, liste_dep FROM liste_id ORDER BY liste_dep, liste_ville;";
$retours = mysqli_query($liaison, $requete);

?>
...


Dans la variable $requete, nous mémorisons la syntaxe Sql permettant de récupérer chaque ville sans redondance (DISTINCT liste_ville) avec le nom du département d'appartenance (liste_dep), à partir de la table liste_id (FROM liste_id). Le tout est trié croissant en priorité sur le département puis sur la ville grâce à la clause ORDER BY. Nous exécutons cette requête sur la base de données grâce à la fonction Php mysqli_query. Il en résulte un tableau de variables représenté par la variable $retours, déclarée et affectée à la volée. Chaque rangée de ce tableau correspond désormais à un enregistrement différent.

Nous devons parcourir l'ensemble de ces enregistrements grâce à une boucle while, comme nous l'avons appris. Il s'agit pour un même département, de récupérer la ville et de la concaténer dans une chaîne, afin de reconstruire le script au fur et à mesure. Il s'agit donc aussi de détecter le changement de département, pour poursuivre l'instruction switch du script dans une autre branche. Mais pour pouvoir écrire dans ce fichier de script, nous devons y accéder en écriture avant la boucle et le refermer à l'issue.
  • A la suite du code précédent, ajouter les instructions suivantes :
<?php
$liaison = mysqli_connect("127.0.0.1", "codePHP", "php123bd");
mysqli_select_db($liaison, "ids");

$requete = "SELECT DISTINCT liste_ville, liste_dep FROM liste_id ORDER BY liste_dep, liste_ville;";
$retours = mysqli_query($liaison, $requete);

$fichier = fopen("js/villes_dep.js", "w");
fclose($fichier);

$fichier = fopen("js/villes_dep.js", "w+");
$chaine = ""; $le_dep=""; $chaine_dep="";

while($retour = mysqli_fetch_array($retours))
{

}
fclose($fichier);

?>
...


Nous exploitons donc la fonction Php fopen qui permet de charger en mémoire le fichier dont le chemin lui est passé en paramètre. Comme nous y accédons en écriture brute (w en second paramètre), nous écrasons ce fichier. Et comme nous le fermons dans la foulée par la fonction fclose, nous le vidons de son contenu. Puis, nous le rouvrons cette fois avec le paramètre w+. Nous y accédons donc en écriture pour ajouter les données les unes à la suite des autres. Puis, nous initions la boucle while qui permet de parcourir l'ensemble des enregistrements résultants de la requête. C'est la fonction Php mysqli_fetch_array qui permet de découper l'information de chaque enregistrement sur les champs qu'il contient. Ces valeurs de champs sont ainsi chargées dans un autre tableau de variables ($retour au singulier) ainsi affecté à la volée. A l'issue de la boucle, nous n'oublions pas de décharger le fichier de la mémoire.

Désormais, il va donc s'agir de reconstruire ce script en fonction des informations récupérées en base de données. Mais avant cela, nous proposons de réaliser une petite vérification intermédiaire.
  • Enregistrer les modifications et basculer sur le navigateur Web,
  • Rafraîchir la page avec la touche F5 du clavier par exemple,
  • Puis, éditer le fichier villes_dep.js,
Comme vous le constatez, grâce à la fonction fopen accédant en écriture (w), ce script externe est désormais vidé de son contenu.

Avant d'y ajouter son code construit dynamiquement, nous devons considérer que le début et la fin de ce script sont statiques. Nous proposons donc de répliquer ces instructions constantes, avant et après la boucle while.
  • Au-dessus et en-dessous de la boucle while, ajouter les instructions Php suivantes :
...
$fichier = fopen("js/villes_dep.js", "w+");
$chaine = ""; $le_dep=""; $chaine_dep="";

fwrite($fichier, "function retour_villes(le_dep)\r\n");
fwrite($fichier, "{\r\n\tvar chaine_villes='';\r\n");
fwrite($fichier, "\r\n\tswitch(le_dep)\r\n\t{\r\n");


while($retour = mysqli_fetch_array($retours))
{

}
fwrite($fichier, "\t}\r\n\r\n\treturn chaine_villes;\r\n}");
fclose($fichier);
?>


C'est la fonction Php fwrite qui permet d'écrire dans le fichier ouvert en mémoire par la fonction fopen. Souvenez-vous, les séquences \r\n permettent de simuler un saut de ligne. La séquence \t quant à elle, permet de reproduire une tabulation pour l'indentation du code.
  • Enregistrer les modifications et basculer sur le navigateur Web,
  • Rafraîchir la page à l'aide de la touche F5,
  • Puis, éditer le fichier de script externe,
Construction dynamique par le code Php du script Javascript permettant de relier les listes déroulantes sur la page Web

Comme vous le constatez, nous avons parfaitement reconstruit le début et la fin du code de la fonction de ce script externe. Désormais, nous devons ajouter l'énumération des départements et pour chacun, la concaténation des villes leur appartenant. Ces instructions doivent être écrites dans les bornes de l'instruction switch, à chaque passage dans la boucle.
  • Dans les bornes de la boucle while et juste après, ajouter les instructions Php mentionnées en gras :
...
$fichier = fopen("js/villes_dep.js","w+");
$chaine = ""; $le_dep=""; $chaine_dep="";

fwrite($fichier, "function retour_villes(le_dep)\r\n");
fwrite($fichier, "{\r\n\tvar chaine_villes='';\r\n");
fwrite($fichier, "\r\n\tswitch(le_dep)\r\n\t{\r\n");

while($retour = mysqli_fetch_array($retours))
{
if($retour["liste_dep"] != $le_dep)
{
if($le_dep!="")
{
$chaine = rtrim($chaine,"|");
$chaine .="';\r\n";
$chaine .= "\t\t\tbreak;\r\n";
}
$le_dep = $retour["liste_dep"];
$chaine_dep .= $retour["liste_dep"]."|";
$chaine .= "\t\tcase '".substr($le_dep,0,2)."':\r\n";
$chaine .= "\t\t\tchaine_villes ='";
}
else
{
$chaine .= trim(utf8_encode($retour["liste_ville"]))."|";
}

}
$chaine = rtrim($chaine,"|");
$chaine .="';\r\n";
$chaine .= "\t\t\tbreak;\r\n";
fwrite($fichier, $chaine);

fwrite($fichier, "\t}\r\n\r\n\treturn chaine_villes;\r\n}");
fclose($fichier);
?>


A chaque passage, nous commençons par vérifier si le département pour l'enregistrement précédent, est différent de l'actuel (if($retour["liste_dep"] != $le_dep)). Dans ce cas en effet, nous devons terminer la précédente chaîne tout en créant la nouvelle branche case du switch Javascript. Mais il ne faut pas que le département mémorisé dans la variable soit vide ($le_dep!=""). Sinon nous comprenons qu'il s'agit du premier passage et donc qu'aucune chaîne de villes n'a encore été reconstruite. Donc s'il n'est pas vide, nous fermons la simple côte et ajoutons l'instruction break signifiant que la branche est terminée. Le raisonnement semble inversé car nous n'avons pas encore écrit dans cette chaîne. Mais souvenez-vous, nous sommes dans une boucle. Le traitement est récursif. Il faut considérer ce qui a pu se produire au passage précédent. Puis, nous créons la nouvelle branche case avec le début de la chaîne pour l'affectation de la variable chaine_villes. Notez que nous en profitons pour concaténer tous les départements dans la variable $chaine_dep. Elle sera utile plus tard.

Dans le cas contraire, donc lorsqu'il ne s'agit pas d'un nouveau département, nous poursuivons l'énumération des villes dans la concaténation. La fonction Php trim supprime les espaces potentiels en bouts de chaîne. La fonction utf8_encode convertit l'information selon le système d'encodage en vigueur dans la page Web, pour la gestion des accents.

Au sortir de la boucle, nous n'oublions pas de réaliser le même traitement qu'au changement de département, pour fermer la dernière chaîne concaténée et ponctuer la syntaxe.
  • Enregistrer les modifications et basculer sur le navigateur Web,
  • Rafraichir la page et sélectionner un département dans la liste déroulante, par exemple : 26-Drome,
  • Puis, déployer la seconde liste déroulante créée à la volée par le code Javascript :
Remplir dynamiquement le contenu de liste déroulante Html enfant selon la liste déroulante parente

Comme vous le constatez, les villes de ce département sont beaucoup plus nombreuses qu'à l'origine. Il s'agit bien des villes du département sélectionné et elles sont énumérées dans l'ordre alphabétique sans redondance. Si vous changez de département, par exemple Ardèche ou Isère, les villes de la seconde liste déroulante s'adaptent aussitôt. Nous avons donc réussi notre pari. Nous avons recréé la fonction Javascript dynamiquement par le code Php. Ainsi, à chaque nouveau chargement, les départements et villes doivent être réactualisés, en fonction des mises à jour survenues dans la base de données MySql. Si vous éditez le script externe, vous constatez que la fonction a en effet parfaitement été reconstruite.

Construction dynamique du script Javascript par le code Php pour lier les listes déroulantes Html

Comme ce script est chargé naturellement dans la section head de la page Web index.php :

<script language='javascript' id='cible' src='js/villes_dep.js'></script>

Il en résulte l'actualisation dynamique des listes déroulantes reliées entre elles. Il est important de comprendre que toutes les actions des internautes au travers des listes ne sollicitent pas le serveur. Par reconstruction dynamique du script externe, la main est passée au code Javascript. C'est donc la machine du client qui gère ces opérations.

En revanche à ce stade, un problème persiste. La seconde liste réagit bien en fonction de la première. Mais la liste des départements est complètement statique. Elle est écrite dans le flux Html de la page Web. En conséquence, elle ne tient pas compte des informations issues de la base de données :

...
<select id="choix_dep" name="choix_dep" class="liste" onChange="charger_villes()">
<option value="00">Sélectionnez un département</option>
<option value="07-Ardèche">07-Ardèche</option>
<option value="26-Drome">26-Drome</option>
<option value="38-Isère">38-Isère</option>
<option value="69-Rhone">69-Rhone</option>
<option value="73-Savoie">73-Savoie</option>
</select>
...


Si vous choisissez le département de la Savoie, vous constatez que la liste liée des villes est vide. Ceci est tout à fait logique. Ce département n'existe pas en base de données. Donc la correspondance n'a pas été créée dans le script externe. C'est la raison pour laquelle nous avons mémorisé la liste de tous les départements dans la variable $chaine_dep. Nous devons l'exploiter pour reconstruire dynamiquement cette première liste déroulante.
  • Dans les bornes des balises Select de la liste déroulante des départements, remplacer le code Html statique par le code Php dynamique suivant :
...
<select id="choix_dep" name="choix_dep" class="liste" onChange="charger_villes()">
<?php
$tout_dep = explode("|",rtrim($chaine_dep,"|"));
echo "<option value='0'>Choisir un département</option>";
foreach($tout_dep as $un_dep)
{
echo "<option value='".utf8_encode($un_dep)."'>".utf8_encode($un_dep)."</option>";
}
?>

</select>
...


Grâce à la fonction Php explode que nous connaissons, nous découpons la chaîne des départements sur le délimiteur (|). Il en résulte un tableau de variables nommé $tout_dep. Nous le parcourons grâce à une boucle foreach que nous avons présentée lors d'une précédente formation. A chaque passage, nous recréons dynamiquement une ligne supplémentaire dans la liste déroulante, avec la valeur du département, grâce à la balise Html option concaténée.
  • Enregistrer les modifications et basculer sur le navigateur Web,
  • Rafraîchir la page Html et déployer la première liste déroulante,
Comme vous le remarquez, l'offre est moins généreuse. Mais cette fois, elle est conforme aux données de la base MySql.

Remplir le contenu de liste déroulante Html par le code Php en fonction des données de la base MySql

Actualisation dynamique des listes déroulantes
Nous proposons de confirmer le dynamisme du système que nous avons bâti pour relier ces listes déroulantes, gérées finalement par le code client. C'est pourquoi il existe un second fichier Sql dans le sous dossier bdd.
  • Dans l'interface d'administration PhpMyAdmin, sélectionner la base de données ids,
  • Cliquer sur l'onglet Importer situé en haut de l'interface,
  • Cliquer sur le bouton Parcourir,
  • Puis, désigner le fichier Sql suite_id.sql situé dans le sous dossier bdd,
  • En bas de l'interface, cliquer sur le bouton Exécuter pour procéder à l'importation,
Si vous affichez le contenu de la table liste_id, elle compte désormais 1186 enregistrements.
  • Revenir sur la page Web et la rafraîchir,
  • Déployer la liste déroulante des départements,
Comme vous le constatez, deux nouveaux éléments sont venus se greffer à la suite : Le Rhône et la Savoie.
  • Sélectionner par exemple le département de la Savoie,
  • Puis, déployer l'affichage de la seconde liste déroulante des villes,
Actualiser le contenu des listes déroulantes reliées entre elles en fonction des informations contenues dans la base de données MySql

Comme vous le constatez, les villes de ce nouveau département, purgées de leurs doublons, sont chargées dynamiquement. Notre système de listes déroulantes en cascade, gérées par le code client, est donc parfaitement fonctionnel. Si vous consultez le code de la fonction du script externe, vous remarquez qu'il a effectivement évolué pour intégrer toutes les nouvelles valeurs issues de la base de données MySql.

 
Sur Facebook
Sur Youtube
Les livres
Contact
Mentions légales



Abonnement à la chaîne Youtube
Partager la formation
Partager sur Facebook
Partager sur Twitter
Partager sur LinkedIn