Geneste lijsten in geneste while-loops

Status
Niet open voor verdere reacties.

JeroenE

Terugkerende gebruiker
Lid geworden
20 mrt 2005
Berichten
1.950
Hallo,
Ik ben een geneste lijst aan het maken dat uiteindelijk een menu moet worden, en ik haal de gegevens uit drie tabellen in dezelfde database.
Hier is de code:
PHP:
<ul id="navlist">
  <?php
  while ($aregionline = mysql_fetch_object($aregionsquer)) {
    if ($aregionline->id < 11) {
      ?>
      <li><?php echo $aregionline->region; ?>
        <ul>
          <?php
          while ($azipcodeline = mysql_fetch_object($azipcodesquer)) {
            if ($azipcodeline->region_id == $aregionline->id) {
              ?>
              <li><?php echo $azipcodeline->location; ?>
                <ul>
                  <?php
                  while ($aicerinkline = mysql_fetch_object($aicerinksquer)) {
                    if ($aicerinkline->zipcode_id == $azipcodeline->id) {
                      ?>
                      <li><?php echo $aicerinkline->name; ?></li>
                      <?php
                    };
                  };
                  ?>
                </ul>
              </li>
              <?php
            };
          };
          ?>
        </ul>
      </li>
      <?php
    };
  };
  ?>
</ul>
Mijn probleem is dat de eerste while-loop het doet, de tweede doet het maar 1 keer ipv 10 keer en de derde doet het al helemaal niet.
Hier kan je het resultaat zien.
Wat doe ik fout?
Alvast bedankt.
Jeroen
 
Wat mij opvalt zijn de ; achter je afsluitende accolades. Waar zijn die voor?

Wat heb je qua debugging geprobeerd?
Wat levert een var_dump($azipcodesquer) (Wanneer je Xdebug geïnstalleerd hebt, anders een print_r) binnen de WHILE van $aregionline op?
 
var_dump geeft een bool(false) en die ; achter de afsluitende accolades is uit gewoonte. Bij javascript gebruik ik die ook.
Hoeft dat niet? Ik dacht dat dat het script duidelijk maakte dat daar de opdracht ten einde was en dat er een nieuwe kon beginnen
 
Voor zover ik weet zijn ze niet nodig.

De (bool) false is apart, het lijkt mij dat daar wat in hoort te zitten.
Wat geeft var_dump($aregionsquer); aan voor de eerste WHILE?
 
Ok, had de verkeerde variabele in de var_dump gezet.
Het resultaat van een var_dump($azipcodesquer) is resource(4) of type (mysql result)
var_dump($aregionsquer) voor de eerste while geeft resource(3) of type (mysql result)
 
Aha, dat is in ieder geval een beter resultaat :)

Binnen de tweede WHILE boven het IF statement plaatst daar dit eens:
PHP:
echo $azipcodeline->region_id .' == '. $aregionline->id .'<br />';
if ($azipcodeline->region_id == $aregionline->id) {

Dan kun je kijken welke $azipcodelines hij allemaal bij langs gaat :)
 
Moet hij normaal niet bij allemaal de $azipcodelines langs gaan?
Hij doet dat dus niet hé :s

Ok, hij loop alle records af tot hij een match tegenkomt. Dan geeft hij de volgende $azipcodeline->location en doet dan verder tot de volgende match, dus dat loopt goed.
What's next? :-)
 
Laatst bewerkt door een moderator:
Dus het probleem met het maar 1x tonen is opgelost? Begrijp ik dat goed?
 
ik heb ook een keer zoiets bij de hand gehad, PHP lijkt zich wat vreemd te gedragen met geneste loops. Ik heb het toen opgelost (lees, omheen gewerkt) door een foreach loop te gebruiken, met daarin while loops, dat werkte wel, al zal er vast wel en nettere oplossing zijn.

Ik snap alleen niet helemaal waarom je met PHP door je hele tabel heen fietst om je resultaten te filteren. Zou het niet beter zijn om je query aan te passen zodat, er (bijvoorbeeld) alleen maar resultaten worden opgehaald waar id<11? Aangenomen dat die kolom geïndexeerd is zou dat veel sneller moeten zijn.
 
Laatst bewerkt:
Het probleem dat het maar 1x getoond wordt, is nog niet opgelost. De bedoeling is dat de bewerking voor iedere provincie herhaald wordt en telkens de ijspistes weergeeft die in die provincie liggen.
Ik zou bijvoorbeeld ook de tabel met ijspistes kunnen wijzigen en daar de postcodes en regios in opslaan, maar ik heb aparte tabellen gebruikt voor toekomstig gebruik met andere toepassingen zodat ik de tabellen zo klein mogelijk kan houden ivm de hoeveelheid webspace die gebruikt wordt.

Als ik jouw oplossing zou gebruiken, Naarling, een query die alleen de resultaten ophaalt waar bijvoorbeeld id<11, dan moet ik die query 11 keer herhalen, maar het is ook een oplossing.

Mocht het dus lukken met de tabellen zoals het is, dan zou dat ideaal zijn.
 
Wat zijn de queries die je nu gebruikt bij de mysql_query()'s?
 
Zoveel geneste loops duidt meestal op een verkeerde gedachtengang. ;)

Daarnaast is PHP begonnen met de deprecation van de mysql_*-functies. Tijd om over te stappen naar PDO of MySQLi dus.
 
@Tha Devil:
PHP:
$aregionssql = "SELECT * from regions ORDER BY id";
$aregionsquer = mysql_query($aregionssql, $sdb) or die(mysql_error());

$azipcodessql = "SELECT * from zipcodes ORDER BY id";
$azipcodesquer = mysql_query($azipcodessql, $sdb) or die(mysql_error());

$aicerinkssql = "SELECT * from icerinks ORDER BY id";
$aicerinksquer = mysql_query($aicerinkssql,$sdb) or die(mysql_error());

@SvU:
Kan je hier wat meer uitleg over geven, want dat is nieuw voor mij.
 
Ik heb het als volgt opgelost:
PHP:
$aregionssql = "SELECT * from regions ORDER BY id";
$aregionsquer = mysql_query($aregionssql, $sdb) or die(mysql_error());

$azipcodessql = "SELECT * from zipcodes ORDER BY id";
$azipcodesquer = mysql_query($azipcodessql, $sdb) or die(mysql_error());

$aicerinkssql = "SELECT * from icerinks ORDER BY id";
$aicerinksquer = mysql_query($aicerinkssql,$sdb) or die(mysql_error());

while ($aregionline = mysql_fetch_object($aregionsquer)) {
  $nregions = count($aregions);
  $aregions[$nregions]["id"] = $aregionline->id;
  $aregions[$nregions]["region"] = $aregionline->region;
  $aregions[$nregions]["icerink"] = false;
};

while ($azipcodeline = mysql_fetch_object($azipcodesquer)) {
  $nzipcodes = count($azipcodes);
  $azipcodes[$nzipcodes]["id"] = $azipcodeline->id;
  $azipcodes[$nzipcodes]["location"] = $azipcodeline->location;
  $azipcodes[$nzipcodes]["region_id"] = $azipcodeline->region_id;
};

while ($aicerinkline = mysql_fetch_object($aicerinksquer)) {
  $nicerinks = count($aicerinks);
  $aicerinks[$nicerinks]["id"] = $aicerinkline->id;
  $aicerinks[$nicerinks]["name"] = $aicerinkline->name;
  $aicerinks[$nicerinks]["period"] = $aicerinkline->period;
  $aicerinks[$nicerinks]["street"] = $aicerinkline->street;
  $aicerinks[$nicerinks]["number"] = $aicerinkline->number;
  $aicerinks[$nicerinks]["pobox"] = $aicerinkline->pobox;
  $aicerinks[$nicerinks]["zipcode_id"] = $aicerinkline->zipcode_id;
  for ($ni = 0; $ni <= $nzipcodes; $ni++) {
    if ($aicerinkline->zipcode_id == $azipcodes[$ni]["id"]) {
      $aicerinks[$nicerinks]["zipcode"] = $azipcodes[$ni]["zipcode"];
      $aicerinks[$nicerinks]["location"] = $azipcodes[$ni]["location"];
      for ($nj = 0; $nj <= $nregions; $nj++) {
        if ($azipcodes[$ni]["region_id"] == $aregions[$nj]["id"]) {
          $aicerinks[$nicerinks]["region"] = $aregions[$nj]["region"];
          $aregions[$nj]["icerink"] = 1;
        };
      };
    };
  };
  $aicerinks[$nicerinks]["phone"] = $aicerinkline->phone;
  $aicerinks[$nicerinks]["fax"] = $aicerinkline->fax;
  $aicerinks[$nicerinks]["cell"] = $aicerinkline->cell;
  $aicerinks[$nicerinks]["email"] = $aicerinkline->email;
  $aicerinks[$nicerinks]["map"] = $aicerinkline->map;
  $aicerinks[$nicerinks]["website"] = $aicerinkline->website;
  $aicerinks[$nicerinks]["monday"] = $aicerinkline->monday;
  $aicerinks[$nicerinks]["tuesday"] = $aicerinkline->tuesday;
  $aicerinks[$nicerinks]["wednesday"] = $aicerinkline->wednesday;
  $aicerinks[$nicerinks]["thursday"] = $aicerinkline->thursday;
  $aicerinks[$nicerinks]["friday"] = $aicerinkline->friday;
  $aicerinks[$nicerinks]["saturday"] = $aicerinkline->saturday;
  $aicerinks[$nicerinks]["sunday"] = $aicerinkline->sunday;
  $aicerinks[$nicerinks]["comment"] = $aicerinkline->comment;
};
?>
<div id="menudiv" style="width: 100%">
  <table id="navtable" align="center" cellpadding="5">
    <tr>
      <?php
      for ($na = 0; $na <= $nregions; $na++) {
        if ($aregions[$na]["icerink"]) {
          ?>
          <td class="navtablehead"><?php echo $aregions[$na]["region"]; ?></td>
          <?php
        };
      };
      ?>
    </tr><tr>
      <?php
      for ($na = 0; $na <= $nregions; $na++) {
        if ($aregions[$na]["icerink"]) {
          ?>
          <td valign="top" class="navtablebody">
            <?php
            for ($nb = 0; $nb <= $nzipcodes; $nb++) {
              if ($azipcodes[$nb]["region_id"] == $aregions[$na]["id"]) {
                for ($nc = 0; $nc <= $nicerinks; $nc++) {
                  if ($aicerinks[$nc]["zipcode_id"] == $azipcodes[$nb]["id"]) {
                    echo ($aicerinks[$nc]["period"] == "") ? "<a href='?irid=" . $aicerinks[$nc]["id"] . "' title='" . $aicerinks[$nc]["name"] . "'>" : "";
                    echo (($aicerinks[$nc]["period"] == "") || ($aicerinks[$nc]["period"] == "schoolperiode")) ? $aicerinks[$nc]["location"] : "";
                    echo ($aicerinks[$nc]["period"] == "") ? "</a><br />" : "";
                    echo ($aicerinks[$nc]["period"] == "schoolperiode") ? "<br />" : "";
                    echo ($aicerinks[$nc]["period"] != "") ? "&nbsp;&nbsp;&nbsp;&nbsp;<a href='?irid=" . $aicerinks[$nc]["id"] . "' title='" . $aicerinks[$nc]["name"] . " " . $aicerinks[$nc]["period"] . "'>" . $aicerinks[$nc]["period"] . "</a><br />" : "";
                  };
                };
              };
            };
            ?>
          </td>
          <?php
        };
      };
      ?>
    </tr>
  </table>
</div>
Hier is het resultaat

Alvast bedankt om mee te denken :-)

Groetjes,

Jeroen
 
Wat SvU bedoelt met deprecation is dat ze de functie als het ware aan het 'uitfaseren' zijn. Dit heeft te maken met verbeterde varianten als PDO / MySqli waarbij wat voordelen te halen zijn op bijvoorbeeld beveiligingsgebied. Google maar eens op 'Prepared statements'. Daarbij wordt MySQL injection (bijna) onmogelijk gemaakt omdat de query eerst wordt gevalideerd voordat deze naar de database wordt gestuurd.

Ik heb niet alle code bekeken maar zo op het eerste idee lijkt het nogal omslachtig allemaal met heel veel code. Daarnaast ga je al je waarden vervolgens handmatig in een array zetten.

Volgens mij (en dit is zo uit het hoofd) kun je ook iets als volgt doen:
PHP:
$data_array = array();

while($row = mysql_fetch_result($query)){
     foreach($row as $key => $value){
              $data_array[$key] = $value;
      }
}
 
Laatst bewerkt door een moderator:
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan