formateur informatique

Extraire les données sans recharger la page PHP

Accueil  >  Technique  >  Php  >  Php Avancé  >  Extraire les données sans recharger la page 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 :


Requêtes serveur sans réinitialiser la page

Dans la formation Php précédente, nous avons relié des listes déroulantes entre elles. Pour cela, nous avons récupéré les travaux que nous avions réalisés lors d'une formation Javascript. Le code Php a permis d'interroger la base de données MySql pour reconstruire le script Javascript, articulant ces listes déroulantes. De fait, nous avons bâti un système de listes déroulantes en cascade ne sollicitant par le serveur. Ce défi technique est particulièrement précieux en production pour les sites Web générant un fort trafic. Mais, à soumission des données du formulaire, nous avions constaté que la page était totalement réinitialisée.

Sources et présentation de la problématique
Dans un premier temps, il s'agit de récupérer les travaux précédents pour poursuivre et améliorer le développement. La décompression fournit le fichier de la page Web principale. Il est nommé index.php et il est accompagné de ses ressources externes dans les sous dossiers.

Ce projet doit être référencé dans EasyPhp comme nous l'avait appris la formation pour débuter la programmation en Php. Bien sûr, les serveurs Http et Database doivent être démarrés.

Ajouter le projet Php des listes déroulantes Ajax dans EasyPhp

Dès lors, un simple clic sur le lien de l'application serveur permet d'accéder à sa page d'accueil. Si des erreurs sont retournées, cela signifie que la connexion à la base de données ids a échoué. Souvenez-vous, dans la formation précédente pour articuler ces listes déroulantes, nous avions récupéré la table liste_id de la base de données ids. Si toutes deux n'existent pas, elles doivent être créées. Ensuite, le sous dossier bdd du dossier de décompression propose les deux sources Sql d'importation des données : debut_id.sql et suite_id.sql.

Le compte suivant doit être créé avec les droits administrateur :
  • Nom d'utilisateur : codePHP,
  • Mot de passe : php123bd,
  • Nom d'hôte (local) : 127.0.0.1,
Il s'agit des informations qu'exploite le code Php pour initialiser la chaîne de connexion.

Dès lors que la base de données MySql et que le compte existent, nous accédons à la page d'accueil sans générer d'erreur. Une liste déroulante est proposée en haut de la page Web. Elle énumère les départements, purgés de leurs doublons, issus de la base de données MySql.
  • Déployer l'affichage de cette liste déroulante et choisir un département,
Listes déroulantes dépendantes reliées par le code Php sur une page Internet

Comme vous le constatez, la représentation graphique du département apparaît aussitôt dans le cadre situé sur la droite de la page Web. Dans le même temps, une nouvelle liste déroulante s'est construite. Il s'agit de la liste déroulante des villes liées au département sélectionné en amont dans la liste parente.

Dans la formation précédente, nous avions conçu un code Php interrogeant la base de données pour énumérer les villes uniques associées à leur département. Sur ces résultats, nous avions reconstruit la fonction Javascript du script externe. C'est elle qui articule ces listes déroulantes reliées, sans solliciter le serveur.
  • 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 comme le Notepad++,
Vous constatez la présence d'une importante portion de code Php en entête de page. C'est ce code précisément qui consiste à reconstruire le fichier de script. Et, en tout début de section, vous remarquez la présence du code initialisant la chaîne de connexion. Elle exploite les identifiants que nous mentionnions précédemment :

<?php
$liaison = mysqli_connect("127.0.0.1", "codePHP", "php123bd");
mysqli_select_db($liaison,"ids");
...


Restituer les données des choix recoupés
Dans le cadre situé sur la gauche de la page Web, nous proposons de restituer les premiers résultats correspondant aux choix recoupés du département et de la ville, émis par l'internaute. Il s'agit donc d'exécuter une requête SQL avec double clause WHERE sur la table liste_id de la base de données ids. Nous produirons ainsi l'extraction des idées de sorties concordantes.

Plus bas dans le code Html de la page index.php, précisément à partir de la ligne 93 pour un éditeur Notepad, vous notez la présence du formulaire Html. Sa méthode est post et il appelle la page index.php elle-même, pour le traitement des données réceptionnées. Il encapsule les contrôles Html, donc les listes déroulantes construites dynamiquement.

D'ailleurs la seconde liste déroulante est créée par la fonction Javascript charger_villes, appelée par la première liste déroulante. Elle est située à partir de la ligne 141 pour un éditeur Notepad. Et c'est ainsi que ces listes sont reliées et articulées.

En ligne 158 pour un éditeur Notepad, vous notez notamment qu'un choix de ville implique la soumission du formulaire Html.

...
chaine_liste = "<select id='choix_ville' name='choix_ville' class='liste' onChange = 'verif_villes(\"" + dep_texte +"\"); document.getElementById(\"formulaire\").submit();'>";
chaine_liste += "<option value='Sélection'>Sélectionner une ville</option>";
...


Nous devons commencer par réceptionner les valeurs postées.
  • Remonter en ligne 114, entre les bornes du calque d'identifiant colonne_gauche,
  • Puis, créer la section de code Php suivante :
...
<div class="colonne" id="colonne_gauche">
<?php
if(isset($_POST["choix_dep"]) && isset($_POST["choix_ville"]))
{
$le_dep = $_POST["choix_dep"];
$la_ville = $_POST["choix_ville"];
echo $le_dep."-".$la_ville;
}
?>

</div>
<div class="colonne" id="colonne_droite">
&nbsp;
</div>
...


Il s'agit de techniques classiques désormais. Grâce à la fonction Php isset, nous testons l'existence des valeurs transmises au serveur, dans une instruction conditionnelle. En effet, au premier chargement de la page, l'internaute n'a pas encore eu le temps de faire ses choix. Nous évitons ainsi de générer des erreurs. Comme toujours, c'est l'instruction PHP $_POST, avec le nom du contrôle en paramètre, qui permet de réceptionner la valeur soumise par ce dernier. La première liste déroulante se nomme choix_dep en effet tandis que la seconde se nomme choix_ville. Nous stockons les valeurs respectives dans des variables. Puis, à titre d'essai, nous les retranscrivons concaténées sur la page Web, en lieu et place, grâce à la fonction Php echo.
  • Enregistrer les modifications (CTRL + S) et basculer sur le navigateur Web,
  • Rafraîchir la page avec la touche F5 du clavier,
  • Choisir un département puis une ville,
Comme vous le constatez, les deux choix émis sont parfaitement réceptionnés et restitués. Nous allons donc pouvoir les exploiter pour interroger la base de données. Néanmoins, un détail chagrine à ce stade. La page Web a été réinitialisée du fait du PostBack. En conséquence, nous avons perdu la trace des sélections dans les listes déroulantes. De plus, la miniature représentant la zone géographique a disparu.

Récupérer côté serveur les valeurs des choix recoupés émis par les listes déroulantes reliées par le code Php

Nous pallierons ce défaut grâce à des techniques Ajax. Dans un premier temps, nous proposons de poursuivre notre développement pour restituer les premiers enregistrements concordants.
  • A la suite du code précédent et à la place de l'instruction echo, ajouter le code Php suivant :
...
<?php
if(isset($_POST["choix_dep"]) && isset($_POST["choix_ville"]))
{
$le_dep = $_POST["choix_dep"];
$la_ville = $_POST["choix_ville"];

$requete = "SELECT liste_nom, liste_activite FROM liste_id WHERE liste_dep='".utf8_decode($le_dep)."' AND liste_ville='".utf8_decode($la_ville)."' ORDER BY liste_nom LIMIT 0,10;";
$retours = mysqli_query($liaison, $requete);
while($retour = mysqli_fetch_array($retours))
{
echo utf8_encode(str_replace("#", "'", $retour["liste_nom"]))."-".utf8_encode(str_replace("#", "'", $retour["liste_activite"]))."<br />";
}

}
?>
...


Nous mémorisons tout d'abord une requête sélection classique dans la variable $requete. Nous recoupons les deux critères sur le département et la ville dans la clause WHERE. Notez l'emploi de la clause LIMIT en toute fin de syntaxe. Elle est équivalente à la clause TOP que nous avions présentée dans la syntaxe des requête SQL, exploitées avec ACCESS. Elle permet de limiter la sélection. Nous n'avons effectivement pas assez de place pour une restitution intégrale. Nous prélevons les 10 premiers enregistrements en partant du premier (0). Comme toujours, c'est ensuite la fonction mysqli_query qui permet d'exécuter cette requête. Il en résulte un tableau de variables ($retours) dans lequel sont rangés tous les enregistrements extraits. Nous initions alors une boucle while pour les parcourir tous. La fonction Php mysqli_fetch_array permet, à chaque passage, de découper l'enregistrement en cours, sur ses informations de champs. De fait, nous pouvons accéder aux données indépendamment grâce au tableau de variables ($retour), ainsi créé à la volée. Puis, nous restituons les informations récoltées tour à tour, grâce à la fonction Php echo.

Comme toujours, nous traitons l'information avec la fonction utf8_encode pour gérer les accents et être en conformité avec le système d'encodage en vigueur. Notez l'exploitation de la fonction Php str_replace. Elle remplace tous les symboles Dièse (#) par une apostrophe. C'est ainsi qu'elle est encodée à l'origine dans cette base de données.
  • Enregistrer les modifications et basculer sur le navigateur Web,
  • Recharger la page en validant sa barre d'adresse,
  • Choisir un département avec la première liste déroulante,
  • Puis, choisir une ville à l'aide de la seconde liste désormais disponible,
Restituer les informations de la base de données MySql correspondant aux choix recoupés des listes déroulantes Html dépendantes

Comme vous le constatez, les 10 premiers enregistrements concordants sont en effet restitués. La présentation laisse certes à désirer mais les résultats sont là. Nous pourrions pallier cette mise en page par imbrications de calques flottants, pour lesquels il serait d'ailleurs judicieux de créer un style CSS dédié.

Aligner et mettre en page les informations restituées de base de données par des calques Html flottants

...
echo "<div style='float:left; width:190px; margin-left:10px; font-size:12px; text-align:left;'>".utf8_encode(str_replace("#", "'", $retour["liste_nom"]))."</div><div style='float:left; width:130px; font-size:10px; text-align:left;'>".utf8_encode(str_replace("#", "'", $retour["liste_activite"]))."</div><br/>";
...


AJAX - Restituer sans recharger
Comme nous l'avons évoqué précédemment, le rechargement de la page après PostBack dégrade la qualité des informations récoltées. Nous avons perdu la trace du département et de la ville sélectionnés. De même, la miniature de la zone géographique n'est plus proposée.

L'astuce consiste à placer le code serveur que nous venons de construire dans une page Php externe. Et c'est cette page qui doit être appelée à soumission du formulaire. Mais cette soumission ne consiste plus en un PostBack classique et brutal. Elle doit être régie par une classe JQuery qu'il convient de récupérer et de référencer dans la page Web du traitement. La décompression conduit au fichier JQuery nommé prototype.js. Il doit être référencé dans la page index.php pour être exploité, au même titre qu'un script externe.
  • Dans la section Head de la page index.php, ajouter la référence à ce script externe :
...
fclose($fichier);
?>
<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Listes déroulantes en cascade en Javascript</title>
<meta name="description" content="Listes déroulantes reliées dynamiquement entre elles par le code client Javascript" />
<meta name="robots" content="index,follow" />
<meta http-equiv="content-language" content="fr" />
<link href='styles/mef.css' rel='stylesheet' type='text/css' />
<script src="js/prototype.js" type="text/javascript"></script>
<script language='javascript' id='cible' src='js/villes_dep.js'></script>
</head>
<body>
...


Désormais, nous devons remplacer la soumission par PostBack, par l'appel d'une fonction qui doit se charger d'établir le lien avec le code Php que nous externaliserons. Nous choisissons de nommer cette fonction : recolter. Et nous devons l'appeler même si nous ne l'avons pas encore créée.
  • Dans la fonction Javascript charger_villes, remplacer la soumission du formulaire (document.getElementById(\"formulaire\").submit()), par l'appel de la fonction recolter :
...
nb_villes = tab_villes.length;
//alert(nb_villes);

chaine_liste = "<select id='choix_ville' name='choix_ville' class='liste' onChange = 'verif_villes(\"" + dep_texte +"\"); recolter();'>";
chaine_liste += "<option value='Sélection'>Sélectionner une ville</option>";

for(var defil=0; defil<nb_villes; defil++)
{
...


Cette fonction Javascript doit désormais exister. C'est elle qui doit établir la liaison avec le traitement Php externalisé, pour empêcher le rechargement de la page Web.
  • Dans la section Head de la page Web, ajouter la section de script avec sa fonction recolter, selon le code suivant :
...
<link href='styles/mef.css' rel='stylesheet' type='text/css' />
<script src="js/prototype.js" type="text/javascript"></script>
<script language='javascript' id='cible' src='js/villes_dep.js'></script>
<script language='javascript' type="text/javascript">
function recolter()
{
document.getElementById("formulaire").request({
onComplete:function(transport){
document.getElementById('colonne_gauche').innerHTML = transport.responseText;
}
});
}
</script>

</head>
<body>
...


Grâce à la référence à cette classe JQuery, c'est la méthode request appliquée sur le formulaire, qui permet de déclencher la transaction avec le code externalisé. Il est à noter que nous n'avons pas encore ni créé, ni appelé cette page. L'évènement onComplete traduit la fin de l'opération pour la réception des informations, par le biais d'une fonction. Cette dernière exploite une variable nommée transport déclarée à la volée. C'est elle qui est utilisée pour réceptionner les informations résultant du traitement externe. Et grâce à sa propriété responseText, nous restituons les résultats directement dans le calque d'identifiant colonne_gauche.
  • A la racine du dossier de décompression, créer le fichier reponse.php,
  • Puis, l'éditer avec le Notepad,
  • Dans la page index.php, couper toute la section de code Php située entre les bornes du calque d'identifiant colonne_gauche,
  • Puis la coller dans le fichier reponse.php,
Quelques adaptations sont nécessaires. Une nouvelle chaîne de connexion doit être créée pour accéder aux données. Elle n'est en effet pas postée. Cette connexion doit être fermée à l'issue des traitements. La fonction echo doit être remplacée. Les résultats doivent être concaténés dans une variable ($chaine) à déclarer avant la boucle. Finalement, son résultat doit être restitué grâce à l'instruction print.
  • Réaliser les adaptations de code Php mentionnées en gras :
<?php
if(isset($_POST["choix_dep"]) && isset($_POST["choix_ville"]))
{
$liaison2 = mysqli_connect("127.0.0.1", "codePHP", "php123bd");
mysqli_select_db($liaison2, "ids");


$le_dep = $_POST["choix_dep"];
$la_ville = $_POST["choix_ville"];

$requete = "SELECT liste_nom, liste_activite FROM liste_id WHERE liste_dep='".utf8_decode($le_dep)."' AND liste_ville='".utf8_decode($la_ville)."' ORDER BY liste_nom LIMIT 0,10;";
$retours = mysqli_query($liaison2, $requete);
$chaine = "";
while($retour = mysqli_fetch_array($retours))
{
$chaine .= "<div style='float:left; width:190px; margin-left:10px; font-size:12px; text-align:left;'>".utf8_encode(str_replace("#", "'", $retour["liste_nom"]))."</div><div style='float:left; width:130px; font-size:10px; text-align:left;'>".utf8_encode(str_replace("#", "'", $retour["liste_activite"]))."</div><br/>";
}

print($chaine);

mysqli_close($liaison2);
}
?>


Il ne reste plus qu'à adapter l'action du formulaire pour désigner cette page de code Php externalisé.
  • Dans le fichier index.php, remplacer la valeur de l'attribut action du formulaire, afin de pointer sur le fichier reponse.php :
...
<form id="formulaire" name="formulaire" method="post" action="reponse.php">
<div class="titre_centre">
<select id="choix_dep" name="choix_dep" class="liste" onChange="charger_villes()">
<option value="00">Sélectionnez un département</option>
<?php
$tous_dep = explode("|", rtrim($chaine_dep,"|"));
foreach($tous_dep as $un_dep)
{
echo "<option value = '".utf8_encode($un_dep)."'>".utf8_encode($un_dep)."</option>";
}
?>
</select>

<div id="calque_ville" class="liste_div" style="float:right;">
&nbsp;
</div>
</div>
</form>
...
  • Enregistrer les modifications des fichiers et basculer sur le navigateur Web,
  • Recharger la page internet en validant sa barre d'adresse par la touche Entrée,
  • Choisir un département avec la première liste déroulante,
  • Puis, choisir une ville dans la seconde liste déroulante créée à la volée,
Extraire les informations de base de données des listes déroulantes sans recharger la page grâce à Ajax

Comme vous le constatez, nous obtenons bien les enregistrements correspondant aux critères recoupés et récoltés par la requête SQL avec clause Where. Mais cette fois, grâce à la technologie AJAX, la page n'est pas rechargée. La transaction est transparente pour l'internaute.

C'est ce système que nous devons développer à grande échelle pour nos sites Web. Les résultats sont plus propres et plus professionnels. Dans une prochaine formation, nous exploiterons de nouveau cette technologie Ajax pour proposer un système de pagination. Ainsi nous pourrons naviguer simplement au travers de tous les enregistrements résultant des requêtes émises par l'internaute.

 
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