Voici la 4e leçon de ce cours. Elle a pour thème la recherche
d'informations dans la base de données que nous avons crée au cours précédent.
Cette recherche peut se faire de 2 manières : soit en utilisant le
formulaire du haut de la page, qui recherche le mot introduit dans
tout la ligne de notre base de données, soit avec le 2e formulaire qui
permet de rechercher uniquement les enregistrements dont le nom, ou le
prénom, ou l'adresse, .. contient le terme entré dans le formulaire.
Pour fonctionner correctement, vous devez bien entendu avoir rempli
votre base de données avec des informations, sinon votre recherche ne
donnera rien.
Le remplissage se fait bien évidemment avec le cours 3.
En plus des explications, ce cours contient 2 fichiers attachés : le
script perl (cours4.cgi) et la page html qui sert d'interface (cours4.htm)
Le but du script est donc récupérer une valeur dans un formulaire et
de vérifier si elle est présente dans un enregistrement de la base de données.
Pour faire cela on lit le fichier, et on regarde ligne par ligne si
elle contient la valeur recherchée. Si c'est la cas, on affiche
l'enregistrement (= la ligne) concerné. Si ce n'est pas le cas, on
passe à l'enregistrement suivant. On répète cette opération jusqu'à ce
qu'on aie traité toutes les lignes du fichier.
[cette description ici indique clairement ce qu'on va faire, on va
faire une boucle et on va tester quelque chose en utilisant des if else]
Nous allons utiliser le même script pour faire les 2 types de
recherches, il nous faut donc un paramètre qui indique quelle
recherche on fait. Pour cela on ajoute le champ caché type via la
ligne <input type="hidden" name="type" value="xxxx"> en html. Ce champ
peut avoir 2 valeurs : recherche ou recherche2
Au début du script, nous allons donc tester le contenu du champ type
pour voir si nous devons effectuer une recherche simple (fonction
Recherche) ou bien 1 recherche plus complexe en tenant compte du nom
de la colonne (fonction Recherche2)
Ce test ce fait via le if else suivant :
if ($in{'type'} eq "recherche")
{ &Recherche;
}
elsif ($in{'type'} eq "recherche2")
{ &Recherche2;
}
else
{ print "Y a un stuuuuuut :)";
}
Si le champ type est égal à recherche, alors on exécute la fonction
Recherche, sinon ; si le champ type est égal à recherche2 alors on
exécute la fonction Recherche2 sinon on affiche "Y a un stuuuuuut :) ".
Nous allons maintenant regarder la fonction Recherche de plus près.
sub Recherche
{
Il s'agit simplement de la déclaration de la fonction Recherche, rien
de bien neuf depuis la leçon passée.
open (DATABASE, "<$db") || die "Can't open $db: $!\n";
Cette ligne ouvre en lecture le fichier dont le nom est contenu dans
la variable db. On voit qu'on ouvre en lecture au caractère < qui
précède le nom du fichier. Lors du cours précédent, on avait ouvert en
écriture à la fin du fichier en utilisant >>.
On donne un nom (un handler) à ce fichier : DATABASE.
@LINES=<DATABASE>;
Cette ligne place tout le contenu du fichier désigné par DATABASE dans
le tableau LINES à l'aide de l'opérateur diamant <XXX>.
Chaque ligne du fichier est placée dans un élément du tableau. Notre
tableau a donc autant d'éléments qu'il n'y avait de lignes dans le fichier.
close(DATABASE);
Je pense qu'il n'y a pas grand chose à dire concernant cette ligne :-)
$SIZE=@LINES;
Cela mets le nombre d'éléments du tableau LINES dans la variable SIZE.
Nous avons donc la taille du tableau LINES, et connaissons donc
l'index du dernier élément.
for ($i = 0; $i <= $SIZE; $i++)
Il s'agit du début d'une boucle. On va initialiser i à 0 ($i = 0) et
tant que i est plus petit ou égal à SIZE ($i <= $SIZE) (qui contient
le nombre d'éléments de notre tableau), on va faire ce qui est entre
les accolades qui délimitent la boucle.
Le $i++ indique que chaque fois qu'on arrive à la fin du code contenu
entre les 2 accolades, on ajoute 1 à i.
{ $_=$LINES[$i];
C'est la 1ere instruction du bloc de code. Elle met le contenu de la i eme
ligne du tableau LINES dans la variable $_ qui est une variable spéciale.
if (/$in{'cle'}/)
teste si $in{'cle '} se trouve dans la variable $_ et comme dans ce
cas ci $_ contient la ligne de notre fichier, on regarde si notre
ligne contient le mot que l'on recherche.
Ce test utilise les expressions régulières.
{ # trouvé enregistrement ok
print $_,"<br>\n";
}
C'est le bloc de code à effectuer si j'ai trouvé le mot recherché dans
la ligne que je suis en train de traiter.
J'affiche donc le contenu de la variable $_ et je mets un <br> pour
faire un retour à la ligne en HTML suivi d'un \n qui signifie nouvelle
ligne dans le code html généré.
Si vous ne voyez pas a quoi sert le \n, essayez avec et sans et pour
voir la différence, regardez le code html qui est généré par le script
pour la page de réponse.
}
Fin du bloc de code de la boucle, c'est dire que l'on a vérifié toutes
les lignes du fichier.
print "<a href=\"$ENV{'HTTP_REFERER'}\">retour à la page de ref</a>";
Voici la ligne qui pose problème à plusieurs d'entre vous pour une
raison ou une autre. Elle n'a pas changé depuis celle du cours
précédent, donc pas besoin d'explications particulières.
}
Cette accolade, indique la fin de la fonction Recherche
La fonction Recherche2 est plus complexe car elle tient compte de la
colonne spécifiée, mais aussi car elle décompose la ligne du fichier
pour la présenter de manière structurée dans un tableau html.
sub Recherche2
{ open (DATABASE, "<$db") || die "Can't open $db: $!\n";
@LINES=<DATABASE>;
close(DATABASE);
$SIZE=@LINES;
Rien de spécial, le début de la fonction est identique à celui de
Recherche, si ce n'est le nom.
print "<table border=1>\n";
Cette ligne permet d'afficher le tag html de début d'un tableau et de
mettre un retour à la ligne à la fin (\n)
for ($i = 0; $i <= $SIZE; $i++)
{ $_=$LINES[$i];
Ces lignes sont identiques à la fonction Recherche. Voir plus haut
pour les explications.
if (/$in{'cle'}/)
Tout comme pour la fonction recherche, cette ligne vérifie si $_
contient la valeur contenue dans in{'cle'} qui correspond au mot
introduit dans le formulaire.
Si $_ contient le mot recherché, on va pousser nos recherches plus
loin, en vérifiant si il est bien dans le champ que l'on a choisi.
{ # trouvé enregistrement qui contient la clé
@data = split(/\|/,$_);
La fonction split, permet de séparer le contenu d'une variable en
différents éléments d'un tableau. Ici je sépare le contenu de $_ le
caractère de séparation est la barre verticale puisque c'est ce
caractère que nous avons utilisé pour séparer les différents champs de
notre formulaire lorsque nous les avons enregistrer dans le fichier.
Les différents éléments seront placés dans le tableau data.
$_ = $data[$in{'colonne'}];
Je mets dans la variable $_ le contenu de l'élément indiqué par $in{'colonne'}.
$in{'colonne'} qu'est ce que c'est ? et comment ca marche ?
En fait pour le comprendre, il faut aller voir dans l'html de la
recherche avancée, j'ai associé une valeur a chaque colonne : le nom
vaut 0, le prénom vaut 1, ...
En fait après le split, le nom est le premier élément du tableau data,
le prénom est le 2e élément, ...
Le premier élément d'un tableau porte le numéro 0, c'est pour cela
qu'a nom j'ai associé 0 (logique non une fois qu'on a compris que les
tableaux commencent a 0)
Donc si j'ai choisi le prénom comme critère, $in{'colonne'} vaut 1 et
donc $data[$in{'colonne'}]; le script perl va effectuer $_ = $data[1];
if (/$in{'cle'}/)
Cette ligne teste toujours si le nom entré dans le formulaire est
contenu dans la variable $_
{ #cette fois la "cellule" contient bien la valeur
Si on arrive ici, c'est que le mot recherche est contenu dans la
colonne que l'on a spécifié.
print "<tr>\n";
Le print permet d'afficher un <tr> qui permet la création d'une
nouvelle ligne dans notre tableau html.
for ($j=0;$j<6;$j++)
{
Il s'agit de la boucle commençant à j = 0 et s'effectuant tant que j
est plus petit que 6. J étant incrémenté de 1 à la fin de chaque itération.
print "<td>$data[$j] </td>\n";
Cette ligne affiche simplement dans des cellules html les différentes
informations concernant la personne trouvée.
Comme je suis dans une boucle de 0 à 5, je fais afficher tous les
éléments du tableau data, chaque élément étant dans une cellule html.
}
Fin de la boucle for
print "</tr>\n";
Affichage d'un tag permettant de fermer la ligne en cours du tableau html.
}
Fin du if dans lequel nous sommes passés car la colonne contenait ce
que nous cherchions.
}
Fin du if ou nous sommes passés car la ligne du fichier contenait le
mot recherché
}
Fin du for permettant de traiter toutes les lignes du fichier.
print "</table>\n";
Affiche le tag fermant notre tableau html. Ce tag est très important,
car si on l'oublie, la page affichée sera vide sous Netscape .
print "<a href=\"$ENV{'HTTP_REFERER'}\">retour à la page de ref</a>";
Le lien habituel vers la page d'ou on vient.
}
L'accolade de fin de la fonction Recherche2
Exercices ou améliorations à apporter :
Faire une mise en page plus sympa pour la fonction Recherche
Faire une recherche plus large qui ne tient pas compte des
majuscules/minuscules
N'afficher un résultat que si le champ contient exactement la valeur
et pas au moins la valeur
...
Comme d'habitude, la suite dans un peu plus d'1 semaine si tout va
bien :) mais on en reparle avant sur la liste en fonction de vos
questions (enfin si vous voulez).
Ne vous contentez pas de tester les exemples sur votre serveur,
essayez de modifier un peu le code perl / html de façon à modifier le
formulaire ou la façon dont sont affichées les données.