Compter les occurences des mots dans une chaine

musatge
Invité n'ayant pas de compte PHPfrance

13 mars 2010, 22:31

Bonjour
Je récupère les mots contenus dans le champ etiquettes de la table articles et je désire compter les occurences de chaque mot pour réaliser un nuage de tags. J'ai écrit le script suivant:
			<?php
 				require 'admin/includes/connexion.php'; 	
				$nuage="";
				$sql = mysql_query('SELECT etiquettes FROM articles') or die();					
				while ($rang = mysql_fetch_assoc($sql)) {
					$nuage=$nuage.",".$rang['etiquettes'];
				}
				$nuage=substr($nuage, 1); 
				$nuage = explode(',',$nuage); // découper la chaîne par rapport aux virgules avec explode() 
				$nuage_compteur=array(); // préparer un tableau vide pour mettre les compteurs 
				foreach($nuage as $etiquette) {			
					while(preg_match("/^([ ]+).*$/",$etiquette,$trouve)) $etiquette=substr($etiquette,strlen($trouve[1])); // supprimer les éventueles espaces devant les éléments de la chaîne
					while(preg_match("/^.*([ ]+)$/",$etiquette,$trouve)) $etiquette=substr($etiquette,0,-((int) strlen($trouve[1]))); // derrière
					$nuage_compteur[$etiquette]++;				
				}
				foreach($nuage_compteur as $etiquette=>$nombre) {
					echo "<li> $nombre $etiquette</li>";
				}
				echo "</ul>";
			?>
mais si il me donne bien le résultat escompté il me renvoie également le message d'erreur suivant:
Notice: Undefined index: posset in C:\Program Files\EasyPHP 3.0\www\nouvelles\nuage.php on line 30
à chaque tour de boucle, la ligne 31 correspondant à
$nuage_compteur[$etiquette]++;

Quel est le problème ?
Cordialement

Mammouth du PHP | 985 Messages

14 mars 2010, 01:05

C'est du costaud, 5 boucles en 30 lignes dont 2 avec un preg_match() :wink:
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

14 mars 2010, 14:05

Le problème que tu rencontres est qu'à un moment donné de ton algorythme, tu fais appel à une valeur d'un tableau alors que celle-ci n'est pas définie :
$nuage_compteur=array(); // ici tu déclares un nouveau tableau vide
foreach($nuage as $etiquette) {                 
   ....
   $nuage_compteur[$etiquette]++; // ici tu fais appel à l'index $etiquette de ton tableau, et tu demandes à php d'incrémenter la valeur qui se trouve à cet endroit.  
}
Ton soucis provient du fait qu'au premier appel de l'index, celui-ci n'est pas défini puisque le tableau est vide. PHP te renvoi alors un message d'avertissement pour te dire qu'il va se débrouiller comme il peut pour te satisfaire, mais qu'à son humble avis, ton code doit avoir un problème car tu lui demandes de modifier des variables alors que celles-ci n'existent pas ;)

Pour résumer, test avant si ton index existe, et si ce n'est pas le cas, initialise le et php te fichera la paix ;)
if (isSet($nuage_compteur[$etiquette])) // si déjà défini on incrémente
   $nuage_compteur[$etiquette]++;
else // sinon on initialise
   $nuage_compteur[$etiquette] = 1;
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Jerems60
Invité n'ayant pas de compte PHPfrance

14 mars 2010, 15:02

Salut,
plutôt que d'utiliser des expressions régulières pour virer les blancs devant et après la chaîne,
tu pourrais utiliser la fonction native trim()
$etiquette=trim($etiquette);
c'est plus simple non ?

Eléphanteau du PHP | 11 Messages

14 mars 2010, 23:35

Merci à vous deux
C'est nickel, je voyais bien que c'était un problème de ce type mais je ne voyais pas la solution.
Simple et élégant.
Merci encore
Cordialement :D

ViPHP
ViPHP | 5462 Messages

15 mars 2010, 12:03

C'est du costaud, 5 boucles en 30 lignes dont 2 avec un preg_match() :wink:
ouai :mrgreen:

allé hop 2 lignes
preg_match_all("/\b[\w'\.-]+\b/u", $text, $matches);	
print_r(array_count_values($matches[0]));
ensuite tu pourrais choisir le nombre de carateres minium

exemple pour 4 carateres :
/\b[\w'\.-]{4,}\b/u