2010-09-18 6 views
1

Je n'arrive pas à foreach à travailler. Peut-être que je ne le comprends pas correctement.Looping avec while et foreach en PHP

Voici mon code:

$statement = "SELECT * FROM categories ORDER BY name ASC"; 
$query = mysql_query($statement) 

... 
... 

$cals = array("sports","general","other","clubs"); 

foreach ($cals as $value) 
{ 
/* echo "<h3>".$value."</h3>"; 
*/ echo "<table width='100%'>"; 
while ($array = mysql_fetch_array($query)) 
    { 
     if ($array['calendar'] == $value) 
     {?> 
<tr> 
    <td><?php echo $array['name']; ?></td> 
    <td><a onclick="update_form('<?php echo $array['name']; ?>', '<?php echo $array['calendar']; ?>')" href="#">Edit</a></td> 
</tr> 
<?php } 
    } 
    echo "</table><br />Value: $value"; 
} 

Le but de cela est d'avoir le foreach changer l'instruction if. J'avais prévu pour la déclaration if de dire: if ($array['calendar'] == "sports") la première fois, if ($array['calendar'] == "general") la deuxième fois, et ainsi de suite. Toutefois, il affiche toutes les tables (dans le code source), mais aucune ligne de table n'est créée après la première pour chaque valeur de tableau. Par exemple, je vois correctement la table des sports, mais je ne vois pas de rangées pour les tables générales, les autres ou les clubs. Il y a des enregistrements dans cette base de données qui devraient apparaître dans chacun d'entre eux. Pourrait-il être un problème avec le temps et si les déclarations? Si je mets manuellement la valeur $ dans l'instruction if à l'une des valeurs du tableau, elle affiche les enregistrements corrects.

Qu'est-ce qui me manque?

données Exemple:

dans la base de données MySQL -

tableau

catégories. champs:

  • id
  • Nom
  • NUM_EVENTS
  • calendrier
  • CALENDAR_URL

Tous ces champs sauf le champ calendrier a des données fictives en elle.

Actuellement, j'ai 5 enregistrements là-bas. Chacun a une valeur de calendrier différente. L'un est le sport, l'autre les clubs et le général. En fonction de la valeur que je place en premier dans le tableau, cela montre seulement qu'une table, de toutes les valeurs avec la première valeur du tableau.

Voici le code source de la page qui:

<table width='100%'><tr> 
    <td>test4</td> 
    <td><a onclick="update_form('test4', 'sports')" href="#">Edit</a></td> 
</tr> 
<tr> 
    <td>test5</td> 

    <td><a onclick="update_form('test5', 'sports')" href="#">Edit</a></td> 
</tr> 
</table><br />Value: sports<table width='100%'></table><br />Value: general<table width='100%'></table><br />Value: other<table width='100%'></table><br />Value: clubs 
+0

Il serait vraiment utile de voir un exemple de jeu de données. Cela semble généralement correct (même si je ne suis pas sûr de ce que l'appel 'next()' est tout au sujet). – timdev

+0

Je me suis débarrassé de ça. J'essayais juste des choses ... lol ... Un échantillon de données ... comme ce qui est dans la base de données? Je vais voir si je peux trouver quelque chose. – eagle0042

+0

Très bien, je n'étais pas sûr de la façon de fournir des exemples de données, mais j'ai ajouté quelques informations supplémentaires. – eagle0042

Répondre

1

D'abord, juste un point de style. Vous pouvez renommer votre variable $query à quelque chose comme $results. Il contient le résultat d'une requête, pas une requête elle-même. Le problème est que vous ne réinitialisez pas le numéro $results. Après la première table, vous avez itéré tout le long du tableau. Lorsque vous arrivez à la fin, et qu'il n'y a plus de lignes à parcourir, mysql_fetch_assoc() renvoie false.

Donc, essayez ceci:

foreach ($cals as $value) 
{ 
    while ($array = mysql_fetch_array($query)) 
    { 
     if ($array['calendar'] == $value) 
     { 
      ?> 
      <tr> 
       <td><?php echo $array['name']; ?></td> 
       <td><a onclick="update_form('<?php echo $array['name']; ?>', '<?php echo $array['calendar']; ?>')" href="#">Edit</a></td> 
      </tr> 
      <?php 
     } 
    } 
    echo "</table><br />Value: $value"; 
    mysql_data_seek($query,0); // <=== Set the resultsets internal pointer back to zero (the first record). 
} 

Le bit important est le mysql_data_seek() sur la seconde dernière ligne.

Vous pouvez également coller ce mysql_data_seek() juste avant la ligne while(), si vous préférez.Vous avez juste besoin de vous assurer que pour chaque itération de la boucle foreach, le pointeur du tableau est réinitialisé avant d'atteindre while().

EDIT: s/reset/mysql_data_seek/

+0

Vous avez raison de dire que vous finirez par épuiser les enregistrements avant de parcourir tous les éléments du tableau, mais 'reset ($ query);' ne vous aidera pas. –

+0

@Salman A - bien sûr que vous avez raison. $ query est un resultset pas un tableau. Réponse mise à jour – timdev

+0

Cela l'a fait. Merci beaucoup. Je suis en train d'examiner certaines des autres méthodes qui ont été affichées ici aussi. – eagle0042

1

Essayez plutôt ...

$result = mysql_query($query); 
while ($array = mysql_fetch_array($result)) { 
... 
} 
0

mysql_fetch_array tableau de rendement indexé par entier si vous voulez tableau asoc changement

while ($array = mysql_fetch_array($query)) 

à cette

while ($array = mysql_fetch_assoc($query)) 
+0

"mysql_fetch_array - Récupère une ligne résultat en tant que tableau associatif, tableau numérique, ou les deux [par défaut]": http://php.net/mysql_fetch_array – timdev

2

Comme jcubic et timdev souligné, il y a quelques problèmes avec le code comme écrit. Cependant, l'algorithme que vous essayez d'utiliser est très inefficace car il boucle sur l'ensemble des résultats pour chaque type de calendrier. Au lieu de cela, vous pouvez utiliser un tri multi-colonnes dans SQL pour le faire en un seul passage:

$query = "SELECT * FROM categories ORDER BY calendar, name"; 
$results = mysql_query($results) 
... 
... 
$last_cal = ''; 
while ($array = mysql_fetch_assoc($query)) 
{ 
    if (!$last_cal) { 
    echo '<table>'; 
    } 
    else if ($array['calendar'] != $last_cal) { 
    echo '</table>'; 
    echo '<table>'; 
    } 
    ?> 
    ....HTML for table row... 
    <?php 
    $last_cal = $array['calendar']; 
} 
+0

En fait, de nos jours nous utilisons toujours 2 boucles - une pour obtenir des données et un à produire. Très utile. –

+0

Problème lors de l'analyse de ce commentaire. Ce qui est pratique d'avoir 2 boucles quand je le ferai? Et pourquoi avez-vous besoin d'une boucle pour obtenir les données? Le db fetch est juste quelques déclarations. – gmarcotte