Twitter

Créer un moteur de recherche avec XmlHttpRequest et PHP

AJAX est une technologie qui permet d’apporter une plus grande richesse dans l’interface et l’ergonomie d’un site.
Si il est bon de ne pas en abuser au risque de dénaturer le document web, on peut se laisser aller à la tentation d’apporter quelques fonctionnalités intéressantes.
Celle que je vous propose ici consiste à intégrer un moteur de recherche à la manière d’un Google Suggest. Sauf qu’ici vous pourrez avoir un code lisible ^^
Je ne vais pas aborder le concept d’AJAX car certains en parlent déjà très bien. Je vous recommande d’ailleur de lire cet article (Anglophobe, s’abstenir).

PS: Ce billet remplace celui qui s’appelle désormais Introduction à XMLHttpRequest et PHP

Principe

Il faut réunir trois principes pour concevoir cet élément d’application. Tout d’abord nous avons besoin de Javascript et de XMLHttpRequest afin de pouvoir communiquer en arrière plan avec le serveur. Nous allons utiliser la classe XHRConnection pour nous faciliter la vie. Ensuite, il est nécessaire d’avoir un service web se chargera de construire le document XML que nous parserons avec l’API DOM. Enfin afin que l’effet visuel soit efficace nous devrons utiliser les CSS.

Le moteur comprendra une zone de résultat (balise ul) qui ne contiendra pas d’élément de liste. C’est cette liste que nous construirons selon le fichier XML généré et renvoyé par le serveur. Selon que la recherche soit prolifique ou non, la zone de résultat sera cachée ou montrée.

Payes ton code

Vous allez voir, c’est en fait très simple à mettre en place. Voici tout d’abord le formulaire :

<form id="formulaire" action="index.php" method="post">
	<fieldset>
	<p>
		<label for="foo">Saisissez les chaines à rechercher dans le champ de formulaire ci-desous :</label>
		<input type="text" name="foo" id="foo" value="" onkeyup="loadData();" />
	</p>
	<ul id="zoneResultats" style="visibility: hidden;"></ul>
	<p>
		Texte à placer pour tester que les réponses s'affichent par dessus... Lorem ipsum ...
	</p>
	</fieldset>
</form>

Voici le code javascript dont vous aurez besoin :

<script type="text/javascript">
// Déclaration de la fonction de Callback
// + ----------------------------------------------------------------------------------
// + afficherResultats
// + Affiche ou non le conteneur en fonction du résultat de la recherche
// + ----------------------------------------------------------------------------------
function afficherResultats(obj) {
	// Construction des noeuds
	var tabResult = obj.responseXML.getElementsByTagName('resultat');
	document.getElementById('zoneResultats').innerHTML = '';
	if (tabResult.length > 0) {
		// On définit la hauteur de la liste en fonction du nombre de rsultats et de la hauteur de ligne
		var hauteur = tabResult.length * 22;
		with(document.getElementById('zoneResultats').style) {
			visibility = 'visible';
			height = hauteur + 'px';
		};
		for (var i = 0; i < tabResult.length; i++) {
			resultat = tabResult.item(i);
			var egt = document.createElement('li');
			var lnk = document.createElement('a');
			var texte = document.createTextNode(resultat.getAttribute('titre'));
			lnk.appendChild(texte);
			lnk.setAttribute('href', resultat.getAttribute('url'));
			lnk.setAttribute('title', resultat.getAttribute('titre'));
			egt.appendChild(lnk);
			document.getElementById('zoneResultats').appendChild(egt);
		}
	}
	else {
		document.getElementById('zoneResultats').style.visibility = 'hidden';
	}
}
// Déclaration de la fonction qui lance la recherche
function loadData() {
	// Création de l'objet
	var XHR = new XHRConnection();
	XHR.appendData("foo", document.getElementById('foo').value);
	// On soumet la requête
	// Signification des paramètres:
	// 	+ On indique à l'objet qu'il faut appeler le fichier search.php
	// 	+ On utilise la méthode POST, adaptée l'envoi d'information
	// 	+ On indique quelle fonction appeler lorsque l'opération a été effectuée
	XHR.sendAndLoad("search.php", "POST", afficherResultats);
}
	</script>

Coté serveur, nous avons ce petit script PHP :

[php]
header("Pragma: no-cache");
header("Expires: 0");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-cache, must-revalidate");
header("Content-type: application/xml");

if(!empty($_REQUEST["foo"])) {
$rqListBillet = "
SELECT *
FROM `blog_blabla`
WHERE `titre` like '" . $_REQUEST["foo"] . "%'
ORDER BY `date_parution` DESC";
$rsListBillet = mysql_query($rqListBillet);
$xml = "";
if (mysql_num_rows($rsListBillet) > 0) {
while ($billet = mysql_fetch_object($rsListBillet)) {
$xml .= "\ntitre) . "\" url=\"/blog/" . $billet->url_page . ".html\" />";
}

}
}
else {
$xml = "";
}
$xml .= "\n
";
echo utf8_encode($xml);
[/php]

Pour la mise en page, veuillez vous référer au fichier suivant: styles.css.

N'oubliez pas de tester le formulaire, ça se passe ici

22 Comments to Créer un moteur de recherche avec XmlHttpRequest et PHP

  1. 24 août 2005 at 16 h 45 min | Permalink

    A quand GeSHi pour ton blog ?

  2. 24 août 2005 at 16 h 47 min | Permalink

    Il était là un temps. Le temps que je me dise que j’allais m’en passer :)

  3. 6 septembre 2005 at 6 h 02 min | Permalink

    Très intéressant. Merci pour ce tutoriel.

  4. Arnaud's Gravatar Arnaud
    29 septembre 2005 at 15 h 58 min | Permalink

    Ca fait un moment que je tourne là dessus pour arriver à faire un truc correct, et en fait mon prob est que ma base de données sur la quelle je tape comporte 150000 articles, donc ca fait un peu lourd à afficher

    J’essaye donc ta méthode, en te remerciant de la clarté du site et des rédactions qui y sont effectuées.

    @+

    Arnaud 8-)

  5. Alle's Gravatar Alle
    9 octobre 2005 at 11 h 50 min | Permalink

    Salut a tous
    voila je suis débutant et je c pas comment utilser les code si je doit tout méttre dans la méme page ou séparer et le nom des page aussi

    si qulqun peut me répondre.
    merci

  6. 10 octobre 2005 at 9 h 40 min | Permalink

    Bonjour Alle,

    je te proposes de formuler ton besoin sur le forum dreamweaver de http://www.media-box.net

    A bientôt.

  7. 2 novembre 2005 at 16 h 08 min | Permalink

    Bonjour a tous,

    Vous n’avez pas peur que cela fasse un peu bcp de requete sur votre server mysql si tu ne passe pas par un cacheSQL … fait un like % a chaque lettre tapé ca peux vite saturer ton sql, sans compter les scripts malfaisant pour flooder ta base.

  8. nicolas's Gravatar nicolas
    7 novembre 2005 at 10 h 38 min | Permalink

    Salut,

    Super pratique, mais j’ai ça ne fonctionne pas si je base ma recherche sur 2 tables (table mot-cles et une autre mot-associes)

    Je lance ma recherche sur tot donc j’ai une 1ere requete sur ‘toto%’ (table mot-cles), je recupere l’id de ce mot-cles et je fais ensuite une autre requete (table mot-associes)(imbrique dans un while de la 1ere requete) sur cette id et c’est sur cette 2ème requette que je fais ton tuto.

    ça ne fonctionne pas….
    ::whistle

    Sais-tu pkoi ?? ou est-ce limité que sur une table ??

    Merci de ta réponse

  9. 7 novembre 2005 at 13 h 17 min | Permalink

    Salut nicolas,

    je te proposes de soumettre ton code sur ce forum:

    http://dreamweaver.media-box.net :)

  10. 25 février 2006 at 15 h 43 min | Permalink

    Denis Cabasson (www.developper.com) dans son article (tutoriel) du 10 février 2006 (Ajax – une autocomplétion pas à pas) fait une très bonne approche, quoi qu\’un peu complexe à mon goût, de la création d\’une liste déroulante en AJAX.Le…

  11. 3 mars 2006 at 10 h 42 min | Permalink

    :]

  12. Pierre's Gravatar Pierre
    9 mars 2006 at 13 h 53 min | Permalink

    Un truc m’échappe : à quel moment se connecte-t-on à la base ?
    De plus je ne comprends pas bien cette ligne :
     »
    $xml .= « \ntitre) . « \ » url=\ »/blog/ » . $billet->url_page . « .html\ » /> »;
    « 

  13. 10 mars 2006 at 3 h 21 min | Permalink

    @Pierre,

    il n’est pas fait ici de détails concernant la connexion à la base de données. Mais il faut le faire bien sûr ;-)

  14. Pierre's Gravatar Pierre
    10 mars 2006 at 12 h 02 min | Permalink

    Merci, en regardant le code de plus près j’ai mieux compris… Par contre je galère pour débugguer le script PHP, pour lequel je ne parviens pas à voir les erreurs.
    Au passage : félicitations :D

  15. mc_cut_killer's Gravatar mc_cut_killer
    24 mars 2006 at 17 h 07 min | Permalink

    Excelent :-)

    Merci pour ce script et le travail que tu fourni …

  16. Brida's Gravatar Brida
    25 mars 2006 at 15 h 10 min | Permalink

    Bonjour,

    Comment faire pour afficher la valeur sélectionnée de la liste dans la zone du formulaire avant le script me redirige sur une autre page.

    merci de votre aide

  17. touriste's Gravatar touriste
    13 avril 2006 at 16 h 36 min | Permalink

    bonjour, ce framework va t’il encore évoluer?
    je fais actuellement une étude sur les frameworks ajax existant et la pérennité est un point essentiel aux différents critères de sélections

  18. Thanh's Gravatar Thanh
    13 avril 2006 at 18 h 38 min | Permalink

    Bonjour,

    j’envisage depuis un certain temps d’ajouter quelques méthodes. Ce n’est pas pour tout de suite mais c’est effectivement dans les tuyaux :)

  19. 18 avril 2006 at 17 h 49 min | Permalink

    Merci pour le tuyaux :-)

  20. martial's Gravatar martial
    26 avril 2006 at 16 h 05 min | Permalink

    Bonjour merci pour ce script il est vraiment très bien cependant si l’on tape un % dans la zone de recherche on voit que la liste descend tres bas comment faire via la css pour limiter à (par exemple) 20 reponses et qu’il y ai un scroll pour descendre plus bas ??

  21. Thanh's Gravatar Thanh
    26 avril 2006 at 19 h 31 min | Permalink

    Martial,

    tu peux faire un LIMIT 0, 20 du coté de la requête MySQL :)

  22. Arte's Gravatar Arte
    28 avril 2006 at 13 h 20 min | Permalink

    Excelent, merci.
    http://www.portia.pl

Saisir un commentaire

Vous pouvez utilisez les balises HTML suivantes, ainsi que les attributs associés : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Photographie

Tranches de vie on Facebook