1. Endlosschleifen in Zählschleifen verhindern

    Stefan · 09.08.08, 10:32 Uhr · Programmierstil · Tags: ,

    Gestern war kein guter Tag: Wir haben ein CMS einer unserer Websites aktualisiert und anfangs ging alles gut, allerdings ca. eine Stunde später ging gar nichts mehr – großes Rätselraten, da lokal alles funktionierte. Nach dem Debuggen der Anwendung haben wir den Übeltäter gefunden: In einem Fremdscript, das schon lange vor dem Update eingesetzt wurde, versteckte sich eine Endlosschleife die nur unter bestimmten Bedingungen eintritt. Folgendes ist passiert:

    Eine Schleife soll aus einer Liste mit Einträgen die letzten drei Einträge ausgeben, die nicht einer bestimmten Kategorie zugeordnet sind. Gelöst wurde das ursprünglich so:

    for ( $i = 0; $i < 3; $i++) {
       if ($entry[$i]["category"] == "xyz") {
          $i––;
          continue;
       }
       // anderer code hier
    }

    Ganz böse Idee! Warum? Sobald ein Eintrag die entsprechende Kategorie aufweist, die ausgelassen werden soll, wird der Schleifenzähler wieder zurückgesetzt. Da der Eintrag allerdings nicht manipuliert wurde und somit immer wieder auf den dafür verantwortlichen Eintrag trifft, der den Schleifenzähler wieder zurücksetzt, entsteht die Endlosschleife.

    Eine kleine Änderung der Schleife löste das Problem: 

    $maxcount = 3;
    $counter = 0;
    $totalEntries = count($entry);
    
    for ($i = 0; $i < $totalEntries; $i++) {
       if ($entry[$i]["category"] == "xyz") {
          continue;
       }
    
       // mach irgendwas
    
       $counter++;
       if ( $counter == $maxcount) {
          break;
       }
    }
    

     
    Ganz wichtig: Schleifenbedingungen in einer Schleife dynamisch zu ändern sollte man nur tun, wenn man weiß, was es für Auswirkungen hat und ist in den meisten Fällen eine blöde Idee! Kommt man trotzdem nicht darum Schleifenbedingungen zu ändern (z.B. in einer While-Schleife die einen bestimmten Zustand erwartet) sollte immer eine Fallback-Lösung implementiert werden, falls Bedingungen nicht eintreffen (z.B. Schleifendurchgänge zählen und ab einem bestimmten Wert aus der Schleife herausspringen)

  2. Kommentare

    1. Eric · 09.08.08, 15:16 Uhr

      Noch besser wäre es natürlich die Daten zuvor korrekt aufzubereiten so dass das Array nur drei Elemente aufweist. Besser ist es also ein zweites Array zu nutzen oder nur die Items des Arrays zu durchlaufen auf die die Bedingung welche du in der Schleife erst überprüfst zutrifft.

    2. Stefan · 09.08.08, 17:02 Uhr

      sehr richtig!

  3. Kommentar schreiben

    XHTML: Du kannst diese Tags nutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Gehe zur polyCODER Startseite