formateur informatique

Cache et résultats de recherche en Php

Accueil  >  Technique  >  Php  >  Php Avancé  >  Cache et résultats de recherche en Php
Livres à télécharger


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

Pour l'intégrer sur votre site internet ou blog, vous pouvez l'embarquer :

Sujets et formations similaires :


Restitution de la base de connaissance : Moteur Php

Dans cette formation Php, nous terminons la conception du moteur de recherche pour le Web. Il est déjà très performant. Dans une première formation, nous avons développé le code Php produisant une extraction stricte, sur la base de tous les mots clés recoupés. Puis, dans une autre formation, nous avons proposé des résultats approchants pertinents, lorsqu'aucun enregistrement ne correspondait précisément.

Moteur de recherche Php pour un site Internet



Ici, nous souhaitons créer un système de cache afin d'optimiser les ressources du serveur. Lorsqu'une demande est récurrente ou récente, nous préférons restituer des résultats déjà connus plutôt que de questionner de nouveau la base de données MySql. L'astuce consiste à inscrire les extractions sur le disque du serveur, dans des fichiers de type texte. Si une nouvelle recherche est formulée et que le fichier existe, son contenu doit être restitué.

Sources et présentation de la problématique
Pour parfaire cette application serveur, nous devons tout d'abord récupérer les travaux du moteur de recherche, là où nous les avions laissés. La décompression conduit au fichier de la page Web principale, nommée index.php. C'est elle qui héberge le moteur de recherche Php tel que nous l'avons développé jusqu'alors. Elle est accompagnée de ses ressources externes dans les sous dossiers. Et à ce titre, le sous dossier bdd fournit les informations de la table formations au format Sql.

Si vous n'avez pas suivi les formations précédentes, grâce à l'interface PhpMyAdmin, vous devez créer la base de données MySql supports. Puis, vous devez y importer le fichier formations.sql du sous dossier bdd. Ensuite et comme le mentionne le fichier connexion.php situé dans le sous dossier commun, vous devez créer un compte utilisateur associé à cette base de données :

...

$liaison = mysqli_connect('127.0.0.1', 'moteur', 'm127T888');
mysqli_select_db($liaison,'supports');
?>
...


Il s'agit donc d'indiquer le nom d'utilisateur et son mot de passe associé ainsi que le nom d'hôte local. Cette chaîne de connexion fournit toutes ces informations. Veillez à attribuer les privilèges nécessaires à ce compte.

Ensuite et comme vous le savez, le projet doit être référencé dans l'interface d'EasyPhp. Un nom doit lui être attribué. Son adresse prélevée depuis l'explorateur Windows doit être renseignée. Les deux serveurs, Http et Database, doivent être démarrés. Une fois tous les réglages accomplis, le projet est accessible dans la liste des applications émulées par EasyPhp.
  • Cliquer sur son lien pour accéder à sa page d'accueil,
Interface Web Php du moteur de recherche pour développer les fichiers de cache

Nous retrouvons l'interface Web avec la zone de saisie pour le moteur de recherche. Si vous tapez et soumettez les mots clés suivants : Références absolues Excel, le code Php restitue les liens avec Url réécrites de toutes les formations correspondant strictement à la demande. Si vous ajoutez un mot clé incohérent pour soumettre la demande suivante : Références absolues Excel Word, le moteur de recherche ne trouve aucune correspondance exacte. De fait, il propose des rubriques connexes pertinentes.

Dans le premier cas, c'est une requête Sql exploitant l'opérateur AND qui effectue l'extraction en considérant tous les mots clés à croiser. Dans le second cas, après vérification de l'échec pour la correspondance stricte, c'est une requête Sql approximative qui est enclenchée. Elle exploite l'opérateur Or. Et comme elle est susceptible de retourner un grand nombre de résultats, pas forcément pertinents, c'est un code Php qui se charge de l'analyse pour déterminer la proportion des mots clés correspondants. C'est ce que nous proposons de constater avant de poursuivre les travaux.
  • A la racine du dossier de décompression, cliquer droit sur le fichier index.php,
  • Dans le menu contextuel, choisir de l'ouvrir dans un éditeur comme le Notepad ++,
Nous accédons à la structure Html et au code Php du moteur de recherche. En lignes 14 et 15 pour un éditeur Notepad, vous notez l'initialisation de la syntaxe des deux requêtes. Elles sont identiques à ce stade :

...
$mots_a_exclure = 'avec|pour|dans|';
$tableau_exclure = explode('|',$mots_a_exclure);
$requete_et='SELECT * FROM formations ';
$requete_ou = $requete_et;

...


Et puis, entre les lignes 39 et 57, c'est avec une boucle for passant en revue les mots clés réceptionnés, que les requêtes sont assemblées différemment. Comme nous l'avons dit, la première exploite l'opérateur AND pour tous les recouper. La seconde est plus approximative avec l'opérateur Sql OR.

...
for($i=0; $i<sizeof($tableau_mots_cles); $i++)
{
$chaque_mot = rtrim($tableau_mots_cles[$i], 's'); //Supprime le s de fin soit le pluriel
if(strlen($chaque_mot)>3)
{
if($compteur==0)
{
$requete_et .= 'WHERE f_motscles LIKE '%'.$chaque_mot.'%' ';
$requete_ou .= 'WHERE f_motscles LIKE '%'.$chaque_mot.'%'';

}
else
{
$requete_et .= 'AND f_motscles LIKE '%'.$chaque_mot.'%' ';
$requete_ou .= 'OR f_motscles LIKE '%'.$chaque_mot.'%' ';

}

$compteur++;
}
}
...


La première requête est alors exécutée sur la base de données MySql : $retours =mysqli_query($liaison, $requete_et). Puis, une boucle while est enclenchée pour parcourir et réceptionner les enregistrements s'ils existent. A titre de vérification, une variable $compteur est exploitée pour dénombrer les résultats.

Et précisément, si aucune correspondance n'a été trouvée, un test en ligne 86 (if($compteur==0)) enclenche l'exécution de la seconde requête ($retours = mysqli_query($liaison, $requete_ou)) pour proposer des rubriques connexes.



Créer des fichiers de cache de recherche
Désormais, avant de déclencher l'exécution de ces requêtes, nous devons nous assurer qu'une base de connaissance correspondante n'existe pas déjà. C'est pourquoi il existe le sous dossier recherches à la racine du dossier de décompression.

Le principe est le suivant : A chaque nouvelle extraction aboutie, nous devons créer un fichier de type texte dans ce sous dossier. Son nom doit correspondre à l'assemblage des mots clés tapés, purgés des accents et des caractères spéciaux. Il s'agit donc d'accéder en écriture aux fichiers externes. Ce sont des techniques que nous avons apprises au cours de formations. Ainsi, nous y inscrirons le contenu de l'extraction, stocké dans la variable $chaine_fiche. Ce code Php doit donc intervenir en toute fin, à l'issue de la restitution des données sur l'interface Web.

De fait, à l'occasion d'une nouvelle recherche, avant d'enclencher l'exécution des requêtes, un code Php doit vérifier l'existence d'un fichier nommé exactement en fonction des mots clés tapés. S'il existe, il doit déterminer s'il est récent. Il s'agit donc d'accéder aux attributs de fichiers externes. Et si tel est le cas, le code Php doit restituer le contenu de ce fichier. De fait, la restitution est instantanée, le serveur n'est pas sollicité pour attaquer la base de données MySql et les ressources sont préservées.

Il s'agit d'une méthode intéressante en production, lorsque le trafic se densifie, pour continuer de proposer des temps de réponse très courts. Vous savez que les robots d'indexation comme Google sont particulièrement sensibles à ce facteur. Il s'agit aussi d'une très bonne méthode pour préserver l'intégrité du site et du serveur face aux robots malveillants. Certains d'entre eux sont programmés pour réaliser des requêtes répétitives et sans fin, dans les moteurs de recherche des sites internet. Ces fichiers de cache agiront comme des miroirs en leur renvoyant continuellement les mêmes résultats.

Nous devons donc commencer par tester l'existence d'un fichier construit sur la base des mots clés retravaillés. Une variable booléenne fera parfaitement l'affaire.
  • Après la ligne 25, pour la dernière affectation de la variable $les_mots_cles, ajouter les instructions Php suivantes, mentionnées en gras :
...
for($i=0; $i<sizeof($tableau_exclure); $i++)
{
$les_mots_cles = str_replace($tableau_exclure[$i], '', $les_mots_cles);
}

$les_mots_cles = str_replace(' ',' ',str_replace(' ', ' ', $les_mots_cles));
$les_mots_cles = str_replace('-',' ', $les_mots_cles);

$nouveau=false;
$fichier_nouveau = 'recherches/'.str_replace(' ', '-', $les_mots_cles).'.txt';
if(file_exists($fichier_nouveau))
{
$d1 = strtotime(date('j F Y H:i', filemtime($fichier_nouveau)));
$d2 = strtotime(date('j F Y H:i'));
$difference = (int)$d2 - (int)$d1;
if($difference > 3600)
$nouveau=true;
}
else
$nouveau=true;


//echo $les_mots_cles;

if(strlen(str_replace(' ', '', $les_mots_cles))<4)
...


Nous déclarons une variable $nouveau que nous initialisons à false. Par défaut et jusqu'à preuve du contraire, nous considérons donc que la demande n'est pas nouvelle et existe dans les fichiers de cache de la base de connaissance. Puis, dans la variable $fichier_nouveau nous stockons le nom du fichier, construit sur la base des mots clés séparés par des tirets. Nous pointons bien sûr dans le sous dossier recherches et lui ajoutons l'extension .txt. Sur la base de ce chemin complet, l'objectif est de tester son existence, prouvant que la recherche a déjà été formulée.

Nous exploitons alors la fonction Php file_exists. Elle est booléenne. Incluse dans une instruction conditionnelle, elle permet de savoir si le fichier dont le chemin lui est passé en paramètre, existe bien. Si tel est le cas, avant de restituer son contenu, nous devons nous assurer qu'il est récent. Nous exploitons des fonctions que nous avions découvertes à l'occasion de la formation Php sur la manipulation des dates.

La première fonction date est exploitée avec deux paramètres. Le premier spécifie le format de sortie et la précision, comme nous l'avions donc appris. Le second ici est la date de dernière modification du fichier concerné. Et c'est la fonction Php filemtime qui permet d'accéder à cet attribut. Bien sûr, elle requiert en paramètre le chemin complet du fichier. Ainsi encapsulé dans la fonction date, il en résulte un objet de type date. Nous convertissons cette information en temps exploitable pour la comparaison à réaliser, grâce à la fonction Php strtotime, que nous avons elle aussi déjà exploitée. Ce résultat est stocké dans la variable $d1.

Puis, nous exploitons de nouveau la fonction Php date, mais cette fois sans second paramètre. Il en résulte l'information sur la date en cours. Avec les attributs passés en premier paramètre, identiques aux précédents, nous récoltons l'information de date avec la précision jusqu'à l'heure et même la minute près (H:i). Le tout est converti en information de temps exploitable pour les comparaisons numériques, là encore grâce à la fonction Php strtotime. C'est la variable $d2 qui hérite de cette donnée.

De fait, nous pouvons réaliser la différence de temps qui existe entre ces deux informations. Nous prenons soin de caster ces deux variables. Cela signifie qu'ainsi préfixées du type entier entre parenthèses ((int)), nous forçons leur interprétation en valeur numérique entière. Du fait du traitement par la fonction strtotime, cette différence entre les deux informations de date est calculée à la seconde près.

Si le test qui suit est vérifié (if($difference > 3600)), nous en concluons que la dernière recherche réalisée sur ces mots clés date de plus d'une heure (60 secondes * 60 minutes = 3600). Dans ce cas, nous affectons la variable $nouveau à true. Ainsi, nous indiquons au code Php que le cache est trop ancien et que la recherche en base de données doit être effectuée. Cette valeur réglée à 3600 est arbitraire. Nous pourrions très bien restituer le contenu d'un fichier de cache pendant une journée entière. Le test devrait alors être bâti sur la valeur 86400 (3600*24). Enfin, dans la branche else de l'instruction conditionnelle, l'issue est la même. Si le nom du fichier construit sur la base des mots clés n'a pas été trouvé par la fonction file_exists, nous savons que la demande est nouvelle. Nous affectons donc la variable $nouveau à true.

Nous devons exploiter cette variable pour décider de la suite du traitement. Devons nous autoriser l'exécution des requêtes ($nouveau = true) ? Au contraire, devons nous restituer les informations détenues en base de connaissances ($nouveau = false) ?

Nous devons englober les traitements qui suivent dans une instruction conditionnelle.
  • Juste avant les tests sur les mots clés tapés par l'internaute, ajouter l'initialisation de l'instruction conditionnelle, comme suit :
...
if($nouveau==true)
{

if(strlen(str_replace(' ', '', $les_mots_cles))<4)
$chaine_fiche='Oups !<br /><br />Le contenu de votre demande est insuffisant pour être traité.';
else if(strlen(str_replace(' ', '', $les_mots_cles))>50)
$chaine_fiche='Oula !<br /><br />Votre demande semble bien compliquée !<br /> Veuillez la simplifier.';
else if(strpos($les_mots_cles, 'a')===false && strpos($les_mots_cles, 'e')===false && strpos($les_mots_cles,'i')===false && strpos($les_mots_cles, 'o')===false && strpos($les_mots_cles, 'u')===false && strpos($les_mots_cles, 'y')===false)
$chaine_fiche='Désolé !<br /><br />Votre demande ne semble pas correcte !<br /> Il faut être plus clair.';
else
{
...


Nous autorisons donc le traitement si et seulement si la variable booléenne vaut true. Cette instruction doit être fermée après la branche else de ce traitement multicritère, soit après l'exécution potentielle des deux requêtes.
  • En bas du code de la section Php, ajouter les lignes suivantes, mentionnées en gras :
...
$compteur++;
if($compteur>=10)
break;
}
}
}
}
}
else
{

}

}
?>
...


Par l'accolade fermante, nous bouclons l'instruction conditionnelle qui englobe tout le code Php destiné à questionner la base de données. Bien entendu, nous prévoyons une branche else supplémentaire. Si le booléen est réglé à false, il indique que le résultat est déjà connu. En conséquence, le fichier de cache doit être chargé pour restituer son contenu et ne pas solliciter le serveur.

Mais avant cela, à chaque nouvelle requête exécutée, l'extraction restituée par la variable $chaine_fiche doit être inscrite en base de connaissance, dans un fichier de cache nommé en fonction des mots clés tapés.
  • A la fin de la branche du if, ajouter le code Php suivant, mentionné en gras :
...
$compteur++;
if($compteur>=10)
break;
}
}
}
}
$cache=fopen($fichier_nouveau, 'w');
fwrite($cache, $chaine_fiche);
fclose($cache);

}
else
{

}
}
?>
...


Nous avions appris ces techniques dans la formation Php pour accéder au contenu des fichiers externes. La fonction fopen permet d'accéder au fichier désigné en premier paramètre ($fichier_nouveau). L'attribut w en second paramètre indique que nous y accédons en écriture. Si le fichier n'existe pas, il est automatiquement créé. S'il existe, il est écrasé. Il en résulte un objet stocké dans la variable $cache. Ce fichier est donc chargé en mémoire. C'est ainsi que nous allons le travailler. La fonction Php fwrite permet d'écrire dans le fichier, désigné par sa variable objet en premier paramètre. Son second paramètre spécifie l'information qu'il s'agit d'y inscrire. La variable $chaine_fiche est le résultat de l'extraction de l'une ou l'autre requête Sql. Enfin, la fonction Php fclose a deux intérêts. Bien sûr, elle vide l'objet du fichier chargé en mémoire. Et dans le même temps, elle inscrit ces informations physiquement sur le disque dur.

De fait, dans la branche else, puisqu'il s'agit de restituer le contenu d'un fichier de cache, nous devons ajouter le code permettant d'accéder à ce dernier en lecture. Une fois l'information récoltée, elle devra être restituée sur la page Web.
  • Dans la branche else de l'instruction conditionnelle, ajouter le code Php mentionné en gras :
...
}
$cache=fopen($fichier_nouveau, 'w');
fwrite($cache, $chaine_fiche);
fclose($cache);
}
else
{
$cache=fopen($fichier_nouveau, 'r');
$chaine_fiche = fread($cache, filesize($fichier_nouveau));
fclose($cache);
$chaine_fiche .= '<div style='float:left; width:100%; padding-top:10px; color:#999999;'><i>Restitution de la base de connaissance</i></div>';

}
}
?>
...


Nous exploitons de nouveau la fonction Php fopen pour charger en mémoire le fichier qui lui est passé en premier paramètre. Mais cette fois, grâce à l'attribut r passé en second paramètre, nous y accédons en lecture. Dès lors, c'est la fonction fread qui permet de récupérer ces informations. Pour cela, nous lui passons la variable objet précédemment créée en premier paramètre. Le deuxième argument consiste à indiquer sur quelle longueur nous souhaitons prélever ces données. Grâce à la fonction Php filesize, nous récupérons l'intégralité du fichier. La fonction filesize retourne en effet la taille de ce dernier en octet. Un octet équivaut à un caractère. En conséquence, nous les prélevons tous. Ce contenu est stocké dans la variable $chaine_fiche. Souvenez-vous, c'est elle qui est restituée sur la page Web, plus bas dans le code Html, dans les bornes du calque d'identifiant colonne_gauche. Ensuite et comme précédemment, nous exploitons la fonction Php fclose pour libérer les ressources mémoire. Enfin, nous ajoutons une mention à la suite de la chaîne récoltée. Elle consiste à informer l'internaute qu'il s'agit d'une restitution issue de la base de connaissance.

Il est temps de tester ce développement. Nous proposons de valider le fonctionnement sur la base des deux requêtes. Et pour cela, nous allons soumettre les mots clés que nous avions exploités dans la formation précédente. L'objectif est de nous assurer qu'un fichier de cache est créé lorsque la requête stricte est exécutée ($requete_et), mais aussi lorsqu'il s'agit de la requête approximative ($requete_ou).
  • Enregistrer les modifications (CTRL + S) et basculer sur le navigateur Web,
  • Dans la zone de saisie, taper tout d'abord les termes suivants : Références absolues Excel,
Nous ne notons pas de changement a priori. Les résultats stricts sont parfaitement restitués en effet.
  • Dans la zone de saisie, taper désormais les termes suivants : Références absolues Excel Word,
Les proportions apparaissent en préfixes des résultats. Ils attestent que la requête approximative a été déclenchée. Dans les deux cas, le fonctionnement est conforme à celui du moteur de recherche que nous avions développé jusqu'alors.
  • Dans l'explorateur Windows, ouvrir le sous dossier recherches du dossier de décompression,
Fichiers de cache du moteur de recherche Php pour restituer les informations de la base de connaissance

Il était vide jusqu'alors. Il archive désormais des fichiers de type texte construits sur la base des mots clés que nous venons de taper. Et comme l'indiquent leurs tailles, ils semblent bien avoir été renseignés.

Contenu Html du fichier de cache mémorisant résultats des requêtes dans moteur de recherche Php



En ouvrant l'un d'entre eux, vous constatez qu'il renferme le code Html, fruit de l'extraction des résultats par l'une ou l'autre requête Sql. Ils doivent donc permettre de restituer ces données pour ne pas les déclencher de nouveau.
  • Revenir sur le navigateur Web,
  • Taper de nouveau les termes de recherche suivants : Références absolues Excel Word,
Restitution des résultats de la base de connaissance pour ne pas solliciter le serveur et la base de données

Les rubriques connexes sont parfaitement proposées. Mais comme l'indique la mention greffée en dessous des résultats, nous avons la certitude qu'ils ont été restitués depuis un fichier de cache. En conséquence, la base de données MySql n'a pas été attaquée. Nous préservons les ressources serveur. Cette remarque est d'autant plus vraie dans un contexte en production où l'on imagine que ces demandes peuvent être formulées toutes les secondes.
  • Taper désormais les mots clés suivants : Mise en page Word,
Extractions du moteur de recherche Php par requêtes sur la base de données MySql

Cette demande n'a jamais été formulée. Cependant, des correspondances strictes ont bien été trouvées. Si vous ouvrez le sous dossier recherches, vous notez la présence du nouveau fichier de cache.

Si vous tapez de nouveau ces termes de recherche : Mise en page Word, vous remarquez qu'il s'agit désormais d'une restitution instantanée de la base de connaissance.

Restituer les informations du serveur stockées sur le disque dur pour ne pas attaquer les bases de données MySql

Cette restitution perdurera une heure, tel que nous avons construit le critère dans le code Php. Ce délai passé, pour ces mêmes termes, les requêtes seront de nouveau exécutées sur la base de données MySql.

Dans la prochaine formation, nous peaufinerons ce moteur de recherche pour qu'il soit totalement abouti. Nous mettrons en application les techniques Ajax que nous avions démontrées au cours d'une autre formation. Leur objectif est de ne pas générer de PostBack pour produire une extraction transparente, conservant les réglages de la page en cours, dont les mots clés saisis dans le moteur.

 
Sur Facebook
Sur G+
Sur Youtube
Les livres
Contact
Mentions légales



Partager la formation
Partager sur Facebook
Partager sur Google+
Partager sur Twitter
Partager sur LinkedIn