8791 sujets

Développement web côté serveur, CMS

Bonjour,

j'ai ici un script php qui permet de récupérer les mots clé de ma BDD et les mettre dans un fichier XML.

Voici le schéma de ma base simplifié:

un champ titre, un champ contenu, un champ mot-clé avec plusieurs entrées.

Par exemple deux articles parle de football, , dans le champ mot-clé, il y aura deux fois le mot "football".

j'aimerais donc que dans mon fichier xml, le mot football apparaisse en premier car il y a deux fois ce mot. Si il y avait trois article avec le mot clé "pomme", pomme apparaitrait en première position avant le mot football.

Je sais pas si j'ai été très clair, bref voici mon code :

Si vous avez une piste ou même un fonction si cela existe ?

Merci d'avance.


	

<?php
header('Content-Type: text/xml;charset=utf-8');
echo(utf8_encode("<?xml version='1.0' encoding='UTF-8' ?><options>"));
if (isset($_GET['debut'])) {
    $debut = utf8_decode($_GET['debut']);
} else {
    $debut = "";
}
$debut = strtolower($debut);

mysql_connect("localhost","root","");

mysql_select_db("test");

//recupere les mot cle de tout les champs avec group_concat
$reponse = mysql_query("SELECT group_concat(motcle) FROM recherche  ");

$liste = explode(',', mysql_result($reponse, 0));



function generateOptions($debut,$liste_unique) {
    $MAX_RETURN = 10;
    $i = 0;
    foreach ($liste_unique as $element) {
        if ($i<$MAX_RETURN && substr($element, 0, strlen($debut))==$debut) {
            echo(utf8_encode("<option>".$element."</option>"));
            $i++;
        }
    }
}

generateOptions($debut,$liste_unique);

echo("</options>");
?>

Modifié par frdiard (19 Apr 2009 - 09:54)
Salut,

Bon ben cette fois encore je ne suis pas sûr de bien comprendre... Smiley murf

Donc je vais supposer que tu parles de la table recherche et que le champ motcle ne contient qu'un seul mot. Dans ce cas je ferais :
$reponse = mysql_query("SELECT motcle, count(*) as combien FROM recherche group by motcle order by combien desc, motcle");
$liste = array();
while($row = mysql_fetch_assoc($reponse)) {
	$liste[] = $row['motcle'];
}
En fait chaque champ mocle contient plusieurs mots clés séparés par des virgules d'où le explode()

Si cinq articles contiennent le mot clé "foot", il sera qu'une seul fois dans le xml ( array_unique() je pense ) mais comme il existe 5 fois, il sera devant le mot clé "pomme" car "pomme" n'est contenu que dans 3 articles.

J'èspère que vous avez compris, pas facile à expliquer, c'est une sorte de tris en fonction du nombre de fois qu'un mot apparait (tout les champs mot clé additionné bien sur ! )

Smiley cligne
frdiard a écrit :
En fait chaque champ mocle contient plusieurs mots clés séparés par des virgules d'où le explode()
Ben en fait le explode c'est moi qui te l'ai suggéré avec le group_concat dans ton dernier sujet donc c'était pas évident...

frdiard a écrit :
array_unique()
Pas vu de array_unique() dans ton code...

frdiard a écrit :
J'èspère que vous avez compris, pas facile à expliquer, c'est une sorte de tris en fonction du nombre de fois qu'un mot apparait (tout les champs mot clé additionné bien sur ! )
Ce que tu veux obtenir est clair mais ça serait plus facile en expliquant clairement le contexte ! Smiley langue

Donc du coup je verrais ça plutôt comme ça :
<?php
mysql_connect("localhost","root","");
mysql_select_db("test");
$reponse = mysql_query("SELECT group_concat(motcle) FROM recherche");
$liste = explode(',', mysql_result($reponse, 0));
$trieur = array();
foreach($liste as $motcle) {
	$trieur[trim(strtolower($motcle))] +=1;
}
arsort($trieur); // contient la liste

// Début facultatif
// cette partie n'est utile que pour trier une seconde fois par ordre alphabétique
$liste = $liste_wrk = array();
$cpt = 0;
foreach($trieur as $motcle => $valeur) {
	if($valeur != $cpt) {
		sort($liste_wrk);
		$liste = array_merge($liste, $liste_wrk);
		$liste_wrk = array();
		$cpt = $valeur;
	}
	$liste_wrk[] = $motcle;
}
sort($liste_wrk);
$liste = array_merge($liste, $liste_wrk); // contient la liste
// Fin facultatif
?>
Salut,

a écrit :
Voici le schéma de ma base simplifié:
un champ titre, un champ contenu, un champ mot-clé avec plusieurs entrées [...] séparés par des virgules.

C'est le schéma même de ta base qui n'est pas bon. Telle qu'elle est actuellement, ta table limite énormément les opérations sur les tags (les mots-clés). Il te faudrait théoriquement trois tables :

Table Article (elle liste tous les articles)
- id
- titre
- contenu

Table Tag (elle liste tous les tags)
- id
- nom (nom du tag)

Table Article_Tag (elle liste quel article possède quels tags)
- id_article
- id_tag

Pour ajouter un tag à un article tu ajoutes un nouvel enregistrement dans la table Article_Tag, avec l'id de l'article et l'id du tag (récupérés dans leurs tables respectives)

Et vu que tu as désormais une table pour les tags, tu peux faire tout et n'importe quoi avec. Récupérer les tags classés par ordre d'importance (du plus utilisé au moins utilisé), comme tu le souhaites, se fait avec cette simple requête :
SELECT id_tag, COUNT(*) FROM Article_Tag GROUP BY id_tag

Modifié par marcv (17 Apr 2009 - 10:07)
Je comprend pas tout a fait ton schéma.

Quand tu dis "id_article" et "id_tag" je dois mettre un seul id_tag par id_article ?

Par exemple

id_article : 13
id_tag: 5
id_article: 13
id_tag : 6

ou

id_article : 13
id_tag : 5, 6

?

Merci en tout cas, sa va bien m'aidé Smiley cligne
Modifié par frdiard (17 Apr 2009 - 10:36)
Sinon Heyoan j'ai essayé ton script mais le xml me sort un erreur :


<br/>
<b>Notice</b>
:  Undefined index:  motcle in 
<b>C:\wamp\www\test\options.php</b>
 on line 
<b>21</b>


Je remet mon script :


//recupere les mot cle de tout les champs avec group_concat
$reponse = mysql_query("SELECT group_concat(motcle) FROM recherche");
$liste = explode(',', mysql_result($reponse, 0));
$trieur = array();
foreach($liste as $motcle) {
	$trieur[trim(strtolower($motcle))] +=1;
}
arsort($trieur); // contient la liste

// Début facultatif
// cette partie n'est utile que pour trier une seconde fois par ordre alphabétique
$liste = $liste_wrk = array();
$cpt = 0;
foreach($trieur as $motcle => $valeur) {
	if($valeur != $cpt) {
		sort($liste_wrk);
		$liste = array_merge($liste, $liste_wrk);
		$liste_wrk = array();
		$cpt = $valeur;
	}
	$liste_wrk[] = $motcle;
}
sort($liste_wrk);
$liste_unique = array_merge($liste, $liste_wrk); // contient la liste
// Fin facultatif




function generateOptions($debut,$liste_unique) {
    $MAX_RETURN = 10;
    $i = 0;
    foreach ($liste_unique as $element) {
        if ($i<$MAX_RETURN && substr($element, 0, strlen($debut))==$debut) {
            echo(utf8_encode("<option>".$element."</option>"));
            $i++;
        }
    }
}

generateOptions($debut,$liste_unique);

echo("</options>");
?>



Sinon, cette méthode m'a l'air pas mal non plus Smiley smile , merci !
a écrit :
Quand tu dis "id_article" et "id_tag" je dois mettre un seul id_tag par id_article ?
Oui, ça doit ressembler à peu près à ça :
[b]Article[/b]
+----+---------------------------------+----------------+
| id | titre                           | contenu        |
+----+---------------------------------+----------------+
|  1 | Analyse du Petit Chaperon rouge | <ici le texte> |
|  2 | Mon avis sur Cendrillon         | <ici le texte> |
|  3 | Une suite pour Millénium ?      | <ici le texte> |
|  4 | abbr et acronym                 | <ici le texte> |
+----+---------------------------------+----------------+

[b]Tag[/b]
+----+-------------+
| id | nom         |
+----+-------------+
|  1 | conte       |
|  2 | littérature |
|  3 | web         |
|  4 | html        |
|  5 | j'aime      |
|  6 | j'aime pas  |
+----+-------------+

[b]Article_Tag[/b]
+------------+--------+
| id_article | id_tag |
+------------+--------+
|          1 |      1 |
|          1 |      2 |
|          1 |      5 |
|          2 |      1 |
|          2 |      2 |
|          2 |      6 |
|          3 |      2 |
|          3 |      5 |
|          4 |      3 |
|          4 |      4 |
|          4 |      5 |
+------------+--------+

Modifié par marcv (17 Apr 2009 - 10:51)
frdiard a écrit :
Sinon Heyoan j'ai essayé ton script mais le xml me sort un erreur
Ben en fait je vais passer la main à marcv parce que j'ai eu la flemme de t'en parler hier mais qu'il a tout à fait raison... et qu'il a l'air motivé pour t'expliquer ! Smiley langue
Bon j'ai créer les tables,

mais maintenant je vois pas bien comment récupérer les mots clés du plus utilisé au moins utilisé dans mon script donné plus haut ?

merci. Si tu peux encore m'aider sur ce coût là. Tout ces changements sa me perturbe ! Smiley confused
Ben la requête devient :
SELECT id_tag, nom, count(*) as combien FROM article_tag, tag 
where id_tag = id 
group by id_tag, nom 
order by combien desc, nom
Désolée mais je vois pas comment faire pour afficher les résultats. La requête j'avais compris mais après ?

par exemple :

$liste = ... ( le résultat de la requete)
Je crois savoir qu'il faut faire une boucle et un array_push() ou quelque chose dans ce genre, mais je ne me rapelle plus de la syntaxe précise.

J'ai plutôt l'habitude de faire des requête simple c'est pour ça. Smiley confused
Modifié par frdiard (17 Apr 2009 - 13:39)
frdiard a écrit :
Je crois savoir qu'il faut faire une boucle et un array_push() ou quelque chose dans ce genre, mais je ne me rapelle plus de la syntaxe précise.
D'où ma suggestion d'apprendre (ou de réviser) car c'est la base de PHP/Mysql. Smiley cligne

frdiard a écrit :
J'ai plutôt l'habitude de faire des requête simple c'est pour ça. Smiley confused
Ben la requête est déjà faite...

Donc ça donne :
$reponse = mysql_query("SELECT id_tag, nom, count(*) as combien FROM article_tag, tag where id_tag = id group by id_tag, nom order by combien desc, nom");
$liste = array();
while($row = mysql_fetch_assoc($reponse)) {
	$liste[] = $row['nom'];
}
Bon, j'ai réussi mais maintenant je ne peux plus me servir de ma page de résultats.

Avant je cherchais avec LIKE dans le champ motcle.

Comme les mots clés sont maintenant séparés de la table articles, je ne sais pas comment procéder pour la recherche ?
$sql = "SELECT distinct a.id, a.titre, a.contenu 
FROM article a, tag t, article_tag at 
WHERE a.id = at.id_article and at.id_tag = t.id and t.nom like '%$motcle%'";
Là encore il existe des tutos...

Par exemple : les jointures.
Modifié par Heyoan (17 Apr 2009 - 14:50)