Page 1 sur 1

liste de produits récupérés d'une BDD: ancre nommée pour acc

Posté : 17 avr. 2009, 01:20
par leica69
Bonjour,
je récupère une liste de produits d'une base SQL.

Je souhaite avoir une liste de lettres A - B - C -... en haut de page pour accéder rapidement aux produits commençant par cette lettre. Je souhaite donc utiliser des ancres nommées.

Ma question est la suivante: Lors de la récupération des données (qui sont déjà par ordre alphabétique), comment, identifier simplement que la première lettre change et y insérer une ancre nommée.

ex:
...
<p>bateau</p>
<p>bus</p>
<p id="c">camion</p>
<p>car</p>
...

Merci pour votre aide

Posté : 17 avr. 2009, 09:26
par Kemper

Code : Tout sélectionner

TANT QUE mot FAIRE SI lettre_courante est vide OU SI lettre courante EST DIFFERENTE DE première lettre mot ALORS lettre_courante <- première lettre mot écrire ancre FinSI écrire mot Fin TANT QUE

liste de produits récupérés d'une BDD: ancre nommée

Posté : 17 avr. 2009, 09:44
par Invité
J'aurais fait un truc dans ce genre :
<?php

// Donnees fictives

$listeProduits=array(
	"abar","abar","abar","abar","abar","abar","abar","abar","abar","abar","abar","abar","abar","abar","abar","abar",
	"afoo","afoo","afoo","afoo","afoo","afoo","afoo","afoo","afoo","afoo","afoo","afoo","afoo","afoo","afoo","afoo",
	"bbar","bbar","bbar","bbar","bbar","bbar","bbar","bbar","bbar","bbar","bbar","bbar","bbar","bbar","bbar","bbar",
	"bfoo","bfoo","bfoo","bfoo","bfoo","bfoo","bfoo","bfoo","bfoo","bfoo","bfoo",
	"dbar",
	"fbar","fbar","fbar","fbar","fbar","fbar","fbar","fbar","fbar","fbar","fbar","fbar","fbar","fbar","fbar",
	"ffoo","ffoo","ffoo","ffoo","ffoo","ffoo","ffoo","ffoo",
	"zend","zend","zend","zend","zend","zend","zend","zend","zend","zend","zend","zend","zend","zend","zend","zend","zend","zend","zend","zend");
	


// Affichage avec ancres nommees

$alphabet=array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z');

$liens ='';
foreach ($alphabet as $lettre) {
	$liens .= '<a href="#'.$lettre.'">[ '.$lettre.' ]</a> ';
}
$liens .='<a href="#">[top]</a>';

$index = '';
foreach ($listeProduits as $produit) {
	if ($produit[0]!=$index) {
		$index=$produit[0];
		echo '<p id="'.$produit[0].'">'.$liens.'</p>';
	}
	echo '<p>'.$produit.'</p>';
}

Posté : 17 avr. 2009, 09:51
par leica69
Merci Invité. J'ai déjà la liste des produits sur la colonne de droite avec un lien sur la page spécifique.
J'ai aussi un descriptif à afficher sous le nom, ce qui ferait de trop gros Arrays à mettre en mémoire.

Je vais passer par les test conditionnels proposés par Kemper.
J'avais ça en tête, mais je me demandais si une moyen plus simple et léger pour le serveur existait.

Merci

Posté : 17 avr. 2009, 11:35
par iclo
Honnêtement, je pense que la solution de Kemper, est la plus légère possible: la boucle pour afficher les produits existe déja, elle n'ajoute qu'un test if qui ne va pas vraiment manger de la ressource.

Bien à toi

Posté : 17 avr. 2009, 13:51
par Invité
Bonjour,

Quelque chose m'échappe :
La solution de Kemper et la mienne ne sont-elles pas finalement assez proches ?
$lettre = '';
foreach ($liste as $mot) {							// TANT QUE mot FAIRE
    if ($mot[0]!=$lettre) {							// SI lettre_courante est vide OU SI lettre courante EST DIFFERENTE DE première lettre mot ALORS
        $lettre=$mot[0]; 							// 	lettre_courante <- première lettre mot
        echo '<p id="'.$mot[0].'">'.$liens.'</p>'; 	//	écrire ancre
    }												// FinSI
    echo '<p>'.$mot.'</p>';							// écrire mot
} 													// Fin TANT QUE
La différence se fait-elle sur le TANT QUE au lieu du POUR CHAQUE ?

Mais bon, c'est peut-être plus une question débutant qu'une question SQL & BDD.

Posté : 17 avr. 2009, 14:07
par leica69
La différence, à mes yeux, vient de l'utilisation d'un Array dans ton cas.

Je récupère mes données de la BDD, c'est à ce moment je je fais la boucle et les tests, sans passer par un ARRAY:

Code : Tout sélectionner

$ancre = ""; //création d'une requête SQL pour obtenir la liste des huiles $requete="SELECT * FROM table ORDER BY nom"; $resultat=mysql_query($requete) or die ("Problème lors de la requête. Erreur: ".mysql_error()); while($ligne=mysql_fetch_array($resultat)){ $premiere_lettre = substr($ligne['nom'],0,1); echo "\n<h3"; if ($ancre == "" OR $ancre != $premiere_lettre){ echo " id='".$premiere_lettre."'"; $ancre = $premiere_lettre; } echo ">$ligne[nom]</h3>"; echo "<p>$ligne[champ2]</p>"; echo "<p>$ligne[champ3]</p>"; }

Posté : 17 avr. 2009, 15:04
par Ryle
Cette solution est effectivement la meilleure. Je vais toutefois juste profiter de ton code pour faire quelques remarques puisque tu parlais de performances :
while($ligne=mysql_fetch_array($resultat)){ 
Si pour accéder aux valeurs de ta requête, tu utilises uniquement les noms des colonnes et pas leur position (ce qui est à mon sens plus lisible et plus facile à maintenir), un mysql_fetch_assoc est plus léger qu'un mysql_fetch_array.
Pour rappel :
- mysql_fetch_row retourne un tableau indexé ($ligne[0], $ligne[1] ...)
- mysql_fetch_assoc retourne un tableau associatif ($ligne['nomColonneA'], $ligne['nomColonneB'] ...)
- mysql_fetch_array retourne les deux ($ligne[0], $ligne['nomColonneA'], $ligne[1], $ligne['nomColonneB'] ...)
if ($ancre == "" OR $ancre != $premiere_lettre)
A moins de savoir très précisément pourquoi tu utilises l'opérateur "OR" de PHP dans tes tests et les impacts que celui-ci peut avoir sur ton test, je te recommandes de préférer l'opérateur "||" pour tes OU. Ca évitera d'éventuels conflits de priorités d'opérateurs :)
A noter que le test $ancre=="" ne sert à rien. En effet, lors de la première itération de ta boucle, la première lettre de ton mot sera nécessairement différente de $ancre qui sera vide. Ce test est donc inutile, pas la peine d'allourdir le code :)
echo "<p>$ligne[champ2]</p>";
Garde l'habitude de sortir tes variables des chaines et de spécifier les délimiteurs autour d'un index littéral :
echo '<p>' . $ligne['champ2'] . '</p>';
Le code est plus lisible (nottament grace à la coloration) et php ne perds pas de temps à interpréter les chaines pour vérifier si jamais elles ne contiendraient pas une variable qu'il lui faudrait absolument interpréter ;)


Voilà, ce sont à mon sens quelques bonnes pratiques à avoir, à partir de là, tu es libre de piocher dedans celles qui t'intéressent :)

Posté : 17 avr. 2009, 15:12
par leica69
Ryle!!!

MERCI pour ces conseils d'optimisation. Je les applique de suite!