Aller au contenu

Créer un dictionnaire avec php/mysql


Ndeko

Sujets conseillés

Bonjour,

Comme je suis nouveau sur ce forum, quelques mots de présentation pour commencer. J'arrive ici depuis la liste de diffusion des Pompeurs. Je ne suis pas du tout un pro de la création web (mais principal adjoint de collège : rien à voir donc, encore que...), mais je crée, dans mon temps libre, un site perso sur le lingala, une langue africaine.

Je me suis mis au php/mysql depuis quelques temps. Pour m'initier, j'ai "suivi" les leçons proposées sur PhpDébutant, qui m'ont semblé fort bien faites. Qu'en pensez-vous ?

Mon projet actuellement : créer un dictionnaire bilingue français-lingala en php/mysql. L'idée est d'utiliser un formulaire de recherche pour obtenir le - ou les - équivalent(s) d'un mot ou d'une expression d'une langue à l'autre.

Mais mon souci est de proposer un outil intuitif, qui rende mon contenu *accessible* quelles que soient (ou presque) les connaissances de l'utilisateur en grammaire et en orthographe. Je ne voudrais pas, par exemple pour obtenir la traduction de "se laver", lui faire subir une mention du genre : "Pour les verbes pronominaux, entrez leur forme simple, sans pronom personnel, et à l'infinitif". Parce que ça, déjà, pour un certain nombre d'utilisateurs, c'est de l'hébreu. Ou de l'israélien. Ou du Raélien, comme vous voudrez !

Par ailleurs, dans le sens lingala-français, se pose la question de l'orthographe du lingala, qui n'est pas codifiée, et présente souvent des variantes à côté d'un usage académiquement plus reconnu. Si un utilisateur a par exemple rencontré dans ses lectures le mot "mapa" (pains au pluriel), il faut pouvoir le ramener à la forme de ce mot au singulier : "lipa", et mieux encore à l'orthographe la plus correcte : "limpa".

Après divers tâtonnements, j'ai pensé m'en tirer de la façon suivante :

La table ('ln_fr') :

Avoir 5 champs : id, fr_entree, fr_sortie, ln_entree, ln_sortie

Dans fr_entree et ln_entree, je compte placer toutes les entrées que l'utilisateur saisira *probablement*.

Exemple avec "limpa" : limpa , lipa , mampa , mapa . Et du côté français : le pain , un pain , du pain , les pains , des pains . (Sans aller trop loin non plus : je ne pourrais pas non plus grand chose pour celui qui écrira "du paim" !)

Dans fr_sortie et ln_sortie, je compte placer les définitions telles qu'elles s'afficheront lorsqu'on aura lancé une requête portant sur les champs d'entrée.

Exemple pour une recherche où on a saisi lipa, ou limpa, ou mapa, ou mampa, on obtiendrait à l'écran :

limpa (pluriel : mampa) : le pain (pluriel : les pains)

Le code (le choix des balises html reste à améliorer, j'en suis conscient.) :

<div id="recherche">

<form action="#resultat" method="post">

<input type="Text" name="mot" size="20" />

<input type="Submit" value="Traduire" />

</form>

</div>

<div id="resultat">

<?php

if(isset($_POST['mot'])) {

$mot = $_POST['mot'];

$db = mysql_connect('localhost', 'root');

mysql_select_db('ln_fr',$db);

$sql = "SELECT ln_sortie,fr_sortie FROM lingala WHERE ln_entree LIKE '$mot %' OR ln_entree LIKE '% $mot' OR ln_entree LIKE '$mot' OR ln_entree LIKE '% $mot %' ";

$req = mysql_query($sql) or die('Erreur SQL !<br />'.$sql.'<br />'.mysql_error());

while($data = mysql_fetch_array($req)) {

echo $data['ln_sortie'].' : '.$data['fr_sortie'].'<br />';

}

mysql_close();

}

?>

</div>

Qu'en pensez-vous ? Voyez-vous des méthodes plus pertinentes ?

Merci beaucoup de me donner votre point de vue !

--

Pascal Grouselle

Lien vers le commentaire
Partager sur d’autres sites

y'a les méthodes reposant sur les distances de levenshtein, qui sont, à ma connaissances, utilisées pour le dictionnaire intégré à Gnome. Grosso modo, ça permet de retrouver le mot le plus proche du mot entré, en comptant le nombre de changements à effectuer (lettres à changer, à retirer, etc.) entre deux mots, et donc, en ne retenant que ceux dont la distance est inférieure à une distance donnée, on peut déterminer quel est le mot souhaité. Ça permet de passer outre une faute de frappe ou d'orthographe, ce qui me semble particulièrement indiqué dans ton cas, vu que l'orthographe, bien que non codifiée, doit quand même être plus ou moins similaires entre les différentes façons d'écrire le mot, non ? C'est pas super-bien expliqué mais bon ;)

Il existe une fonction levenshtein() en PHP, mais je crains que ça ne soit plus difficile à faire directement en SQL...

Modifié par Nudrema
Lien vers le commentaire
Partager sur d’autres sites

Tu devrais faire une table avec les mots 'normaux' en francais, et une table de correspondance entre ce mot et les variations possible de ce mot. Tu aurais un truc du genre :

id_mot..|..mot...|..langue..|..traduction

.....1.....|..limpa.|.....li.......|..pain........

...

id_var..|..variante.|..langue..|.id_mot

1.........|...lipa.......|....li........|....1

2.........|...mampa.|....li........|....1

3 ........|...mapa....|....li........|....1

4....

Ainsi, lorsque l'on tape un mot, tu fais une recherche dans 'variante', pour voir si le mot existe. (avec les %% eventuellement). Une fois trouvé le mot, tu regarde l'id_mot de cet enregistrement, et tu cherches dans la première table ce mot.

Pour mampa, si quelqu'un tape 'mampa', tu fais :

SELECT mot,traduction
FROM table1,table2
WHERE variante = '".$mot."'
AND table1.id_mot = table2.id_mot

et ca ne peut que marcher. De plus, c'est très évolutif. Tu peux construire ta base en plusieurs fois, sans avoir à entrer tous les mots de la première fois.

ps : mets tout de meme 'limpa' (le mot original) dans la table2 ;)

Anonymus.

Lien vers le commentaire
Partager sur d’autres sites

Ta suggestion est intéressante. Mais je ne saisis pas bien l'avantage qu'il y a de saisir les variantes dans une table à part, plutôt que dans un champ à part. De plus, peux-tu m'expliquer à quoi sert ton champ "langue", présente dans les deux tables ? Merci !

--

Pascal Grouselle

Lien vers le commentaire
Partager sur d’autres sites

Pour : l'avantage qu'il y a de saisir les variantes dans une table à part

Simple. Tu as 2 variantes ? Tu créé 2 champs. Mais tu t'apercois que, dans certains cas, tu auras 4 variantes. Tu reprends ta table, tu ajoutes 2 champs, ca t'en fais 4. Tu te rends compte que, dans certains cas, ce ne sont pas 4, mais 6 variantes qu'il te faut. Tu fais donc les champs supplémentaires, etc..

D'un autre coté, tu vas me dire : Je fais 10 champs, et je suis tranquille. Malheureusement, tu trouveras des cas où il y a 11 variantes. Tu vas faire des tables avec 255 champs ??

Non, la solution est de prévoir tous les cas, même ceux où tu auras 256 variantes (bon, ca ne doit pas arriver souvent).

Avec la solution que je donne, tu peux avoir de 0 (zero) à .. autant de champs que tu veux. Ca gère tous les cas de figure. Et il n'y a pas de champs qui sont vides en quasi permanence.

D'un autre coté, tu sais toujours dans quel champ se trouve ta variante, si tu veux, par exemple, la modifier.

Un exemple :

Dans le cas que tu proposes, tu auras les formulaires pour 6 champs. Si tu dois en créer un autre, c'est l'ensemble des formulaires, de la saisie, etc qui sera à revoir. Concrètement, ca donnera du code comme ca :

SELECT id,champ1,champ2,champ3,champ4,champ5,champ6 FROM table

Les champs de formulaire seront de la même sorte.

Si tu veux faire une recherche, tu vas la faire sur quel champ ? Sur tous les champs. Donc :

WHERE champ1 LIKE var1 OR champ2 LIKE var1 OR champ3 LIKE var1 OR champ4 LIKE var1 OR champ5 LIKE var1 OR champ6 LIKE var1

Ce n'est pas trop gérable. Tu arrives rapidement à saturation, à du code qui ne veut plus rien dire.

On s'y retrouve, bien sûr, mais c'est franchement moyen.

Avec une solution

WHERE variante = '".$mot."'

Tu arrives à du code beaucoup plus clair, même si ca parait plus ardu au début. Et au moins, c'est évolutif... quelque soit le nombre de variantes (singulier, pluriel, féminin, masculin,.. neutre, etc.)

Pour langue :

Dans l'enregistrement :

.....1.....|..limpa.|.....li.......|..pain........

Il te suffit de dire :

SELECT id_mot,mot,langue,traduction FROM table1 WHERE langue='li'

Pour avoir tous les mots (sans les variantes), de la langue en question.

Pour avoir toutes les variantes, il suffit de faire pareil dans la table 2.

Si tu veux ajouter une langue, c'est HYPER facile, je te laisse imaginer ta solution pour incorporer ton système avec :

francais/anglais/limpa, à savoir :

id, fr_entree, fr_sortie, ln_entree, ln_sortie,... ?

et ma solution

id_mot..|..mot...|..langue..|..traduction

où langue peut prendre autant de langues que tu veux. Bon.. langue peut contenir un chiffre au lieu de lettres, il y a moins de risques d'erreurs, mais ca, c'est toi qui voit ;)

Voilà. N'hésites pas si tu as d'autres questions ;)

Lien vers le commentaire
Partager sur d’autres sites

l'avantage qu'il y a de saisir les variantes dans une table à part : Simple. Tu as 2 variantes ? Tu créé 2 champs. Mais tu t'apercois que, dans certains cas, tu auras 4 variantes. Tu reprends ta table, tu ajoutes 2 champs, ca t'en fais 4. Tu te rends compte que, dans certains cas, ce ne sont pas 4, mais 6 variantes qu'il te faut. Tu fais donc les champs supplémentaires, etc..

OK, mais je ne pensais pas procéder comme cela, mais plutôt comme ceci, dans une table unique effectivement :

a) placer toutes les entrées possibles dans un seul champ fr_entree, ou ln_entree, séparées par des espaces + virgules

Exemples :

ln_entree : limpa , lipa , mapa , mampa

fr_entree : le pain , un pain , du pain , les pains , des pains

B) avoir dans les champs de sortie correspondants des libellés du style :

ln_sortie : limpa (nom, pluriel : mampa)

fr_sortie : pain (nom masculin, pluriel : pains)

c) faire porter la requête sur ln_entree, ou fr_entree, selon la page html du dictionnaire (français-lingala ou lingala-français) , avec une requête du type :

WHERE ln_entree LIKE '$mot %' //pour une chaîne de caractères présente au début d'un champ

OR ln_entree LIKE '% $mot' //pour une chaîne présente à la fin d'un champ

OR ln_entree LIKE '$mot' //pour une chaîne srtictement égale au champ

OR ln_entree LIKE '% $mot %' // pour une chaîne présente à l'intérieur d'un champ

Sauf erreur de ma part, donc, je ne pense pas devoir créer un nouveau champ à chaque fois que j'introduis une nouvelle variante dans la table. Cela étant, ton idée de tables séparées me plaît bien aussi. Cela me rappelle, par comparaison, les css externes aux fichiers html. Mais j'ai toujours du mal à en percevoir les points forts par rapport à ma première solution. Je suis prêt à "sauter le pas", mais j'aimerais le faire en pleine conscience de ce que je fais ! Si tu peux m'éclairer, merci !!

--

Pascal Grouselle

Lien vers le commentaire
Partager sur d’autres sites

WHERE ln_entree LIKE '$mot %'

OR ln_entree LIKE '% $mot'

OR ln_entree LIKE '$mot' OR ln_entree LIKE '% $mot %'

Ce genre de requètes, appliqué à un mot tel que :

anticonstitutionnellement

te fera sortir sortir aussi bien :

constitution

que :

elle

ment

tu

tic

..

bref, ca risque d'être assez flou.

Une solution serait alors de comparer parmi chaque mot, entre virgule. Mais c'est plutot complexe à mettre en place (pas trop non plus, mais bon)

En fait, la solution que je te donne correspond assez bien à la logique des bases de données :

1 enregistrement pour 1 type de données.

L'entité, dans tes explications, c'est le 'mot', donc il est normal qu'il ait un champ à lui tout seul.

Un MCD ressortirait la même chose.

Voilà.

Anonymus.

Lien vers le commentaire
Partager sur d’autres sites

Convaincu !!! J'ai fait des essais, et cela tourne bien. Merci pour tes conseils.

Cela permet de surcroît d'utiliser une requête avec le signe =, du type :

WHERE ... = ... , au lieu de LIKE '$mot %' OR LIKE '% $mot' . [1 espace avant et après %]

et donc, on évite, sur une requête portant par exemple sur "la", d'afficher toutes les entrées portant sur des noms féminins ("la table, la maison, la voiture, etc....")

Je m'oriente donc vers la création des tables suivantes (j'ai aussi éclaté les tables de variantes portant sur l'une et l'autre langue) :

1) dictionnaire (id_mot, mot_fr, mot_ln)

2) entree_fr (id_entree_fr, entree_valeur_fr, id_mot_fr)

3) entree_ln (id_entree_ln, entree_valeur_ln, id_mot_ln)

Je vais à présent exploiter les tabels reliées pour créer des tables contenant des phrases-exemples. Car à un même mot du dictionnaire peuvent être associés plusieurs exemples. A creuser...

Merci encore, tu m'as apporté un éclairage précieux sur cette pratique !

--

Pascal Grouselle

Lien vers le commentaire
Partager sur d’autres sites

Je vais à présent exploiter les tables reliées pour créer des tables contenant des phrases-exemples. Car à un même mot du dictionnaire peuvent être associés plusieurs exemples. A creuser...

Bon, après plusieurs tentatives pour ce faire, je sèche encore...

Voici donc ce à quoi je souhaite aboutir :

Lorsque l'utilisateur saisit un mot lingala dans le formulaire, on lui donne

1) la traduction de ce mot en français (exemple : limpa : pain), et cela quelle que soit l'orthographe qu'il a pu utiliser lors de sa saisie (lipa, limpa)

2) une ou des phrases-exemples traduites (exemple : Nalingi limpa. : J'aime le pain.)

Pour cela j'ai créé 3 tables :

dictionnnaire :

..id_mot..|..mot_ln..|..mot_fr..

..1.......|..limpa...|..pain....

..2.......|..kopo....|..verre...

variantes :

..id_var..|..id_mot..|..variante..

..1.......|..1............|..lipa...

..2.......|..1............|..limpa...

..3.......|..1............|..mapa...

..4.......|..1............|..mampa...

exemples :

..id_ex..|..id_mot..|ex_ln..............|..ex_fr..

..1.......|..1............|..Nalingi lipa...|..J'aime le pain...

..2.......|..1............|..kolia lipa......|..manger du pain...

L'idée, pour une requête = à lipa, ou limpa, ou mapa, ou mampa, c'est d'afficher ce mot dans sa graphie correcte puis sa traduction : limpa : pain , puis les exemples qui lui sont associés.

J'ai franchi le cap de la première étape grâce aux conseils d'Anonymus, mais je n'arrive pas à formuler la requête qui puisse afficher les exemples. Merci pour votre aide !

--

Pascal Grouselle

Lien vers le commentaire
Partager sur d’autres sites

J'ai résolu mon pb !!

<div id="recherche_fr-ln">
<form action="#resultat_fr_ln" method="post">
<input type="Text" name="mot2" size="20" />
<input type="Submit" value="Traduire" />
</form>
</div>

<div id="resultat_fr_ln">
<?php
if(isset($_POST['mot2']))
{
$mot = $_POST['mot2'];
$db = mysql_connect('localhost', 'pgrouselle', '300197');
mysql_select_db('lingala',$db);
$sql = "SELECT mot_ln,mot_fr,mot_cat FROM dictionnaire,variantes_fr WHERE variante_fr='$mot' AND variantes_fr.id_mot = dictionnaire.id_mot ORDER BY 'mot_fr' ";
$req = mysql_query($sql) or die('Erreur SQL !<br />'.$sql.'<br />'.mysql_error());

if(mysql_num_rows($req) == 0)
 {
echo '<p>Désolé, ce mot ne figure pas dans le dictionnaire.</p>';
 }
else
 {
echo '<dl>';
while($data = mysql_fetch_array($req))
 {
echo '<dt>'.$data['mot_fr'].' ['.$data['mot_cat'].']</dt>
<dd>'.$data['mot_ln'];
$data_ex = $data['mot_fr'];
$sql_ex = "SELECT exemple_ln,exemple_fr FROM dictionnaire,exemples WHERE mot_fr='$data_ex' AND exemples.id_mot = dictionnaire.id_mot";
$req_ex = mysql_query($sql_ex) or die('Erreur SQL !<br />'.$sql_ex.'<br />'.mysql_error());
while($data = mysql_fetch_array($req_ex))
   {
echo '<br />'.$data['exemple_fr'].' : '.$data['exemple_ln'];
   }
echo '</dd>';
 }
echo '</dl>';
mysql_close();
 }
}
?>
</div>

Lien vers le commentaire
Partager sur d’autres sites

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...