2010-09-01 19 views
2

c'est ma première question en stackoverflow.Existe-t-il un meilleur moyen de regrouper les résultats de requête avec une boucle en PHP?

J'ai deux tables MYSQL: catégories et produits. Je gère les résultats de la requête avec une boucle while en PHP pour regrouper chaque catégorie avec ses produits. C'est la première fois que je fais quelque chose, et je pense que je l'ai fait très "astucieux/hardcoded" (désolé pour mon anglais). Je pense que cela devrait être une meilleure façon de le faire. Donc, je voudrais demander aux programmeurs professionnels. Voici mon code:

CREATE TABLE IF NOT EXISTS `categories` (
`id` int(11) NOT NULL auto_increment, 
`name` text NOT NULL, 
PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ; 


CREATE TABLE IF NOT EXISTS `products` (
`id` int(11) NOT NULL auto_increment, 
`name` text NOT NULL, 
`description` text NOT NULL, 
`category` int(11) NOT NULL, 
`photo` int(11) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=33 ; 

J'ai une requête qui retourne des produits relationed avec leur catégorie:

SELECT categories.name as category,products.name as product 
FROM categories 
INNER JOIN products ON(categories.id = products.category) 

Avec PHP que je gère les résultats pour créer une liste non ordonnée pour chaque catégorie avec ses produits:

<?php 
$category = '';//A control variable 

while($row = mysql_fetch_array($query)) 
{ 
    //if its a new category I start a new <ul> 
    if($row['category'] != $category) 
    { 
     //If it´s not the firt category I need to close previous one 
     if($category != '') 
     { 
      echo "</ul>\n"; 
     } 
     //I start the new <ul> 
     echo '<h2>' . $row['category'] . '</h2>'; 
     echo '<ul>'; 
    } 

    //I create the correspondient <li> 
    echo '<li>' . $row['product'] . "</li>\n"; 

    //Asign the value of actual category for the next time in the loop 
    $category = $row['category']; 

} 

//I neeed to close last <ul> 
echo "</ul>\n"; 
?> 

Y a-t-il une meilleure façon de faire cette opération? Merci d'avance pour vos réponses!

+2

Vous pouvez faire une commande par le nom de la catégorie, à assurez-vous qu'ils sont tous ensemble. –

+0

Merci pour le conseil. Je ne l'ai pas spécifié parce que sql renvoie les résultats commandés par categories.name. Si ce n'était pas le cas, je ne pourrais pas construire le ul comme je le veux. – FranQ

+1

l'instruction telle quelle ne peut pas garantir qu'elle renvoie les choses commandées, si vous la laissez comme cela, vous pouvez trouver votre code inattendu plus tard lorsque sql renvoie une séquence différente où toutes les catégories ne sont pas regroupées. Mieux vaut ajouter l'ordre pour s'assurer qu'il n'y aura pas de problèmes plus tard. – mrjohn

Répondre

4

Il est toujours préférable de ne pas mélanger HTML avec PHP.

Puisque vous voulez mon avis (codeur PHP vétéran de 12 ans environ), je vais code juste à partir de zéro réel rapide:

<?php 
$pdo = new PDO($dsn, $user, $pass); 

$sql = "SELECT categories.name as category,products.name as product 
FROM categories 
INNER JOIN products ON(categories.id = products.category)"; 

$stmt = $pdo->prepare($sql); 
$stmt->execute(); 

$categories = array(); 
while (($row = $stmt->fetch(PDO::FETCH_ASSOC))) 
{ 
    $category = $row['category']; 
    $categories[$category][] = $row['product']; 
} 

// In your view: 
?> 
<html> 
    <body> 
<?php 
    foreach ($categories as $category => $products) 
    { 
?> 
     <h2><?php echo $category; ?></h2> 
     <ul class="products"> 
<?php 
     foreach ($products as $product) 
     { 
?> 
      <li><?php echo $product; ?></li> 
<?php 
     } 
?> 
     </ul> 
<?php 
    } 
?> 
    </body> 
</html> 
+0

Merci pour votre code et vos conseils. Je pense que c'est la réponse exacte à ma question: créer un tableau avec les résultats et l'ouvrir avec un foreach(). Le lien donné par premiso à propos de Hierarchical Data est très utile aussi. – FranQ

+0

Pourriez-vous également voter pour cette réponse? ça aide ma réputation. Merci mec. –

+0

Également, s'il vous plaît éviter d'imbriquer HTML en PHP dans la mesure du possible. C'est ** OK ** et même ** préférable ** d'intégrer le code ** sans logique ** dans un modèle HTML, mais ** totalement faux ** pour intégrer la logique métier dans une vue. Par exemple. Si vous vous trouvez à faire beaucoup plus que de sortir du texte dans une vue, vous le faites mal. –

3

Je suggère de lire en Hierarchical Data. Une bonne lecture. Vous devriez particulièrement faire attention au modèle de jeu imbriqué.

Cela prend un peu à apprendre et prend un peu de temps à mettre en œuvre, mais cela en vaut la peine pour le résultat final!

+0

Wow, je ne savais pas que j'étais dans une situation si complexe! Merci pour le lien. Il sera très utile pour moi d'en apprendre plus sur les bases de données, le modèle de jeu imbriqué et la mise en œuvre de données avec structure arborescente. – FranQ

+0

nous utilisons cette même approche hiérarchique où je travaille, et ce n'est en aucun cas facile. Mais les alternatives sont encore pires. Les catégories imbriquées illimitées et les nœuds multi-parents sont des bêtes très compliquées. –

+0

Oui, ce n'est pas facile du tout, surtout quand on ajoute/crée des objets. Mais une fois que le système est en place, il est 10 fois plus facile et plus efficace que l'alternative. Il vaut la peine de lire sur pour acquérir la connaissance en tout cas :) –