Gregor: php-Versuchsaufbau schlägt fehl

Hallo Forum,

eigentlich will ich wissen, wie man in einer Funktion ein statisches Array resettet.

Habe mir deshalb ein kleines Versuchsscript geschrieben, aber selbst das schlägt fehl, daher m eine Fragen:

  1. Warum endet mein Script in einer Endlosschleife?
  2. Wie resette ich bei jeder neuen $id das statische Array $foo[] ?

Gregor

function test($id,$i,$betrag)
{
    static $foo = [];
    $foo[$i] = $foo[$i] + $betrag;
    echo "Betrag: ".$i.": ".$foo[$i]."<br>";
}

for($id = 1;$id++;$id <= 5) {
    for($i = 0;$i++;$i < 11) {
        test($id,$i,$i);
    }
}
  1. Hallo Gregor,

    die Endlosschleife kommt, weil Du die Teile 2 und 3 der for-Schleife vertauscht hast:

    for( init; test; re-init) {
       ...
    }
    

    also

    for( $id=1; $id<=5; $id++) {
       ...
    }
    

    Wegen der Reset-Logik würde ich komplett anders vorgehen und ein Objekt verwenden, das eine reset- und eine add-Methode hat (oder wie auch immer man die sinnvoll benennt).

    Um in deiner Funktion bei einem id-Wechsel das Array zu löschen, musst Du die ID vom letzten Aufruf speichern. Ändert sie sich, weist Du [] an das Array zu.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rolf,

      Hallo Gregor,

      die Endlosschleife kommt, weil Du die Teile 2 und 3 der for-Schleife vertauscht hast:

      Hab ich gar nicht gemerkt. 🤐

      Um in deiner Funktion bei einem id-Wechsel das Array zu löschen, musst Du die ID vom letzten Aufruf speichern. Ändert sie sich, weist Du [] an das Array zu.

      Extern oder innerhalb der Funktion?

      Und warum kommt jetzt hier nicht das raus, was ich wollte?

      function test($id,$i,$betrag)
      {
          static $foo = [];
          $foo[$i] = $foo[$i] + $betrag;
          echo "Betrag: ".$id."/".$i.": ".$foo[$i]."<br>";
      }
      
      for($id = 1;$id <= 5;$id++) {
          for($i = 0;$i < 11;$i++) {
              test($id,$i,'100');
          }
      }
      

      Ich hätte vermutet, dass der betrag pro $i um 100 Einheiten ansteigt. Er steigt aber pro $id um 100 Einheiten und bleibt innerhalb des Durchlaufes gleich.

      Betrag: 1/0: 100
      Betrag: 1/1: 100
      Betrag: 1/2: 100
      Betrag: 1/3: 100
      Betrag: 1/4: 100
      Betrag: 1/5: 100
      Betrag: 1/6: 100
      Betrag: 1/7: 100
      Betrag: 1/8: 100
      Betrag: 1/9: 100
      Betrag: 1/10: 100
      Betrag: 2/0: 200
      Betrag: 2/1: 200
      Betrag: 2/2: 200
      Betrag: 2/3: 200
      Betrag: 2/4: 200
      Betrag: 2/5: 200
      Betrag: 2/6: 200
      Betrag: 2/7: 200
      Betrag: 2/8: 200
      Betrag: 2/9: 200
      Betrag: 2/10: 200
      Betrag: 3/0: 300
      

      Ich brauche

      Betrag: 1/0: 100
      Betrag: 1/1: 200
      Betrag: 1/2: 300
      Betrag: 1/3: 400
      Betrag: 1/4: 500
      Betrag: 1/5: 600
      Betrag: 1/6: 700
      Betrag: 1/7: 800
      Betrag: 1/8: 900
      Betrag: 1/9: 1000
      Betrag: 1/10: 100
      Betrag: 2/0: 200
      Betrag: 2/1: 300
      Betrag: 2/2: 400
      usw.
      
      1. Hallo Gregor,

        Um in deiner Funktion bei einem id-Wechsel das Array zu löschen, musst Du die ID vom letzten Aufruf speichern. Ändert sie sich, weist Du [] an das Array zu.

        Extern oder innerhalb der Funktion?

        Intern, weil eine static-Variable in test() von außen nicht zugänglich ist. Aber dieses Thema hat sich soeben erledigt weil ich deine Absichten ganz falsch verstanden habe.

        test($id,$i,'100');

        Du solltest Zahlen als Zahl und nicht als Zeichenkette speichern. Wo kommt im echten Leben diese '100' her? Wenn sie aus einer DB oder einem $_GET/$_POST Eintrag kommt, wäre der Aufruf von intval() oder floatval() nützlich, um einen Zahlenwert zu erhalten.

        Ich brauche

        Betrag: 1/0: 100
        Betrag: 1/1: 200
        ...
        Betrag: 1/9: 1000
        Betrag: 1/10: 100
        Betrag: 2/0: 200
        Betrag: 2/1: 300
        

        Ich nehme an, du bist bei 1/10 verrutscht und willst da 1100 haben. Ab 2/0 sollte es dann wieder mit 100 losgehen. Gelle?

        In dem Fall musst Du in der test-Funktion die $id als Index verwenden. $i brauchst Du dort gar nicht mehr und mein Klassenbeispiel ist auch nicht für Dich passend.

        Ein "Reset" des Arrays ist dann auch nicht nötig. Du addierst die Beträge unter ihrer jeweiligen ID auf und fertig. Oder ich verstehe Dich immer noch falsch.

        Wenn Du die Beträge so erhältst, wie es deine Testschleifen suggerieren - also so, dass alle Beträge zu einer $id nacheinander kommen - dann brauchst Du eigentlich gar kein Array. Dann reicht

        for ($id=1; $id<=5; $id++) {
           $summe = 0;
           for ($i=0; $id<=11; $i++) {
              $summe += 100;
           }
           echo "Summe für $id ist $summe<br>";
        }
        

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Nachtrag: die Frage, wie Du an die aufsummierten Werte herankommst, ist für mich noch offen. $foo ist außerhalb von test() nicht verfügbar.

          Möglicherweise programmierst Du Dich gerade in eine Ecke hinein, wo Du nicht gut wieder herauskommst?

          Könntest Du vielleicht das Problem beschreiben, das Du lösen willst, anstatt über Probleme einer MÖGLICHERWEISE untauglichen Lösung zu diskutieren?

          Rolf

          --
          sumpsi - posui - obstruxi
          1. Nachtrag: die Frage, wie Du an die aufsummierten Werte herankommst, ist für mich noch offen. $foo ist außerhalb von test() nicht verfügbar.

            Stimmt. Im Original ist natürlich ein return vorgesehen.

            Es ist wie gesagt ein Versuchsaufbau, aus denn Lösung ich dann im Original umsetze, woran es gerade bei mir hakt.

            Vorschlag: Könnten wir es "auf meine Weise" lösen und ich sag anschließend, ob es geholfen hat oder nicht? Nicht sauer sein, aber ich bin sehr sicher, wenn ich meinen Testcode so modifizieren könnte, dass ich das gewünschte Ergebnis erhalte, ist auch mein Problem im Original gelöst.

            Ich nehme an, du bist bei 1/10 verrutscht und willst da 1100 haben. Ab 2/0 sollte es dann wieder mit 100 losgehen. Gelle?

            Ja, da hattest Du recht.

            Gregor

        2. Hallo Rolf,

          Ein "Reset" des Arrays ist dann auch nicht nötig. Du addierst die Beträge unter ihrer jeweiligen ID auf und fertig. Oder ich verstehe Dich immer noch falsch.

          Leider ja. Ich brauche schon zwingend meine Funktion, weil ich die von verschiedenen Scripten nutze. Der hier gezeigte Code soll ja nur mein eigentliches Problem auf die wesentlichen Fragen gekürzt darstellen.

          Wenn Du die Beträge so erhältst, wie es deine Testschleifen suggerieren - also so, dass alle Beträge zu einer $id nacheinander kommen - dann brauchst Du eigentlich gar kein Array. Dann reicht

          for ($id=1; $id<=5; $id++) {
             $summe = 0;
             for ($i=0; $id<=11; $i++) {
                $summe += 100;
             }
             echo "Summe für $id ist $summe<br>";
          }
          

          Ja, das hätte ich wohl schon hin bekommen. 😉

          Leider muss es die Funktion sein.
          Ich kann ja nicht in jedem Script nun das machen, was ich eigentlich über die Funktion ausgliedern wollte.

          Gregor

          1. Hallo Gregor,

            gut. Aber vielleicht spezifizierst Du doch mal, welches Problem genau die Funktion lösen soll.

            Es ist übrigens auch gar kein guter Stil, wenn Du aus einem "main.php" (oder so) einen Haufen Includes hinzuholst, diese wiederum anderes includieren und dann aus diesem ganzen Schwarm von irgendwo eine zentrale Funktion gerufen wird, um irgendwelche Werte zu aggregieren.

            Zugegeben, ich predige hier vom Leuchtturm aus 35 Jahren Berufserfahrung, in dessen Fundament viele Megabytes an unglaublich schmuddeligem Code einbetoniert liegen. Aber so wie Gunnar die Zugänglichkeit und Bedienbarkeit verkündet, versuche ich das mit Clean Code (und bekomme regelmäßig selbst Lektionen darin).

            Rolf

            --
            sumpsi - posui - obstruxi
            1. Hallo Gregor,

              gut. Aber vielleicht spezifizierst Du doch mal, welches Problem genau die Funktion lösen soll.

              Hallo Rolf,

              ich habe irgendwie immer noch den Eindruck, dass Du eine andere Lösung für mich suchst und nicht meinen Weg mitgehen möchtest.

              Die Grundfunktion soll so aussehen:

              function test($id,$i,$betrag)
              {
                  static $foo = [];
                  $foo[$i] = $foo[$i] + $betrag;
                  echo "Betrag: ".$id."/".$i.": ".$foo[$i]."<br>";
              }
              

              und über diese Schleife(n) bedient werden:

              for($id = 1;$id <= 5;$id++) {
                  for($i = 0;$i < 11;$i++) {
                      test($id,$i,'100');
                  }
              }
              
              

              Hierzu muss ich das statische Array $foo innerhalb der Innenschleife um den Betrag erhöhen, der als Parameter $betrag in die Funktion einfließt.

              Bei wechselndem Parameter $id soll das statische Array zurückgesetzt werden.

              Mein Ziel ist dieser Output:

              Betrag: 1/0: 100
              Betrag: 1/1: 200
              ...
              Betrag: 1/9: 1000
              Betrag: 1/10: 1000
              Betrag: 2/0: 200
              Betrag: 2/1: 300
              

              Und ich möchte es wirklich mit meinem Code lösen, auch wenn es anders noch besser geht. Ich habe nur nichts davon, wenn ich die bessere Lösung nicht verstehe oder nicht ins Original übertragen kann.

              Gregor

              1. Lieber Gregor,

                Du verbeißt Dich da in einer vermeintlichen technischen Lösung zu einem Problem, das in Wirklichkeit ein anderes ist.

                Die Grundfunktion soll so aussehen:

                Nein! Du brauchst eine Lösung für ein bestimmtes Problem, egal(!!) wie sie wirklich aussieht, solange sie Dein Problem exakt so löst, wie Du es benötigst. Der Code könnte auch völlig(!) anders aussehen.

                und über diese Schleife(n) bedient werden:

                Vielleicht auch nicht. Das kommt, wie immer, ganz darauf an. Lass Dich mal auf etwas ungewisses ein und freue Dich auf eine vielleicht ganz unerwartete Lösung.

                Hierzu muss ich das statische Array $foo innerhalb der Innenschleife um den Betrag erhöhen, der als Parameter $betrag in die Funktion einfließt.

                Oder Du „musst“ etwas völlig anderes. Was Du wirklich musst, ist Dein eigentliches Problem lösen. Und das sieht so aus:

                Betrag: 1/0: 100
                Betrag: 1/1: 200
                ...
                Betrag: 1/9: 1000
                Betrag: 1/10: 1000
                Betrag: 2/0: 200
                Betrag: 2/1: 300
                

                Siehst Du? Das hier ist Dein Problem. Die Lösung dazu kann ganz anders aussehen, als Du bisher angenommen hast.

                Und ich möchte es wirklich mit meinem Code lösen, auch wenn es anders noch besser geht.

                Warum eigentlich? Hast Du Angst vor irgend etwas? Mir ist klar, dass Du Deinen Code bis zu einem gewissen Grad verstehst. Das gibt Dir ein gewisses Gefühl der Sicherheit. Aber offensichtlich tut Dein Code nicht das, was Du möchtest. Und Du verstehst nicht, warum (was genau macht das Wort static in Deinem Code und wozu brauchst Du das?). Aber anstatt Dir aufzeigen zu lassen, wie man das am besten löst, um dabei genauer zu verstehen, was da in Deinem Programm wie genau passiert, beharrst Du darauf, Deinen vielleicht nicht zielführenden Code mit Gewalt beizubehalten.

                Ich habe nur nichts davon, wenn ich die bessere Lösung nicht verstehe oder nicht ins Original übertragen kann.

                So, da genau liegt jetzt der Hase im Pfeffer, wie man das so schön sagt. Na, dann lass uns doch genau darüber sprechen!

                Wie genau sieht denn das Original aus? Und was genau ist das zu lösende Problem dabei? Dein oben gezeigter Output sieht mir eher wie eine Näherung an das aus, was Du tatsächlich zu erreichen suchst. Also hilft nur, wenn Du etwas mehr an Hintergrundinfo preisgibst, damit man Dir wirklich „helfen“ kann.

                Liebe Grüße

                Felix Riesterer

                1. Hallo Felix,

                  Und Du verstehst nicht, warum (was genau macht das Wort static in Deinem Code und wozu brauchst Du das?).

                  Oh. Davon bin ich jetzt einfach mal ausgegangen, dass Gregor weiß, was eine static Deklaration in einer PHP Funktion tut. Ich hab's zur Sicherheit mal verlunken[1].

                  Aber wo wir schon dabei sind:

                  Hierzu muss ich das statische Array $foo innerhalb der Innenschleife um den Betrag erhöhen, der als Parameter $betrag in die Funktion einfließt.

                  Wie erhöht man ein Array? Antwort: so, wie man das Ticket für einen Bus kontrolliert. Also gar nicht. Man kontrolliert das Ticket eines Passagiers. Und erhöht einen einzelnen Wert in einem Array. Haben wir hier auch ein Grundverständnisproblem?

                  Rolf

                  --
                  sumpsi - posui - obstruxi

                  1. verklingen, verklang, verklungen. Demnach wohl auch verlinken, verlank, verlunken. Oder? Ich hab ja schließlich auf's deutsche Manual verlunken. ↩︎

              2. Mein Ziel ist dieser Output:

                Betrag: 1/0: 100
                Betrag: 1/1: 200
                ...
                Betrag: 1/9: 1000
                Betrag: 1/10: 1000
                Betrag: 2/0: 200
                Betrag: 2/1: 300
                

                Mit dem gezeigten „wenn das, dann das“ kommen wir hier nicht weiter. Dein Code liefert falsche Ergebnisse und das obige Raum für eine unbegrenzte Anzahl an Spekulationen. Gib uns eine klare und verstehbare Berechnungsvorschrift im Sinne von

                Z=funktion(x, y)=x*100+y*100
                

                Und ich möchte es wirklich mit meinem Code lösen,

                Erst mal die Aufgabe.

                Ich habe nur nichts davon, wenn ich die bessere Lösung nicht verstehe

                Dein Code ist kaputt, Du verstehst den ausweislich Deiner Probleme auch nicht. Mit dem kannst Du es ergo nicht lösen. Der Schienenersatzverkehr fährt nicht am Bahnsteig ab sondern vom Bahnhofsvorplatz. Ende der Durchsage.

              3. Hallo Gregor,

                ich habe irgendwie immer noch den Eindruck, dass Du eine andere Lösung für mich suchst und nicht meinen Weg mitgehen möchtest.

                Richtig. Das liegt daran, dass dein Datenbeispiel und deine übrigen Beschreibungen nicht zusammenpassen. Deswegen habe ich eine genauere Spezifikation dessen, was Du eigentlich tun willst, erbeten.

                Bei wechselndem Parameter $id soll das statische Array zurückgesetzt werden.

                Okay. Definiere "zurücksetzen". Für mich bedeutet das: Alle Werte aus dem Array löschen, so dass nur noch [] da steht.

                Ich verstehe nicht, warum Du das tun willst. Ich verstehe auch nicht, warum Du $i als Index für das Array nimmst. Wenn Du pro $id Werte aufsummieren willst, müsste dann nicht $id der Index sein? $i scheint mir völlig unerheblich für die Summierung. Zumindest dann, wenn ich dein Beispiel anschaue.

                $foo muss nur dann ein Array sein, wenn Du

                • pro $id mehr als eine Summe bilden willst - was dein Beispiel aber nicht nahelegt

                oder

                • die Summen für alle $id in diesem Array sammeln willst

                Im ersten Fall müsstest Du bei einem $id-Wechsel das Array löschen. Und nach jedem Funktionsaufruf den aktuellen Wert des Arrays zurückgeben, damit man die Summen überhaupt noch hat. Aber wie gesagt: Dein Beispiel legt das nicht nahe und daher halte ich diesen Fall für wenig relevant.

                Im zweiten Fall ist kein Zurücksetzen nötig, und an Stelle einer static-Variablen wäre eine global Variable sinnvoller (oder ein Objekt…), damit Du an die gebildeten Summen ohne Verrenkungen herankommst.

                Wie ist denn der Datenverlauf in deinem Programm? Ist es so wie in deiner Testdemo, dass die $id Werte separat nacheinander kommen? Oder können sie auch durcheinander erscheinen? Damit wären wir beim zweiten Fall, und ein Zurücksetzen wäre sogar schädlich.

                Wenn die $id nacheinander kommen und auch nur eine Summe je $id zu bilden ist, reicht für $foo eine einfache Variable. Ein Array ist unnötig. Du bräuchtest dann aber auch eine static- oder global-Variable für die aktive ID, und wenn der $id Parameter von der aktiven ID abweicht, setzt Du $foo auf 0 (setzt es zurück).

                Mit der Zusatzvariable meine ich das so:

                function test($id, $i, $betrag) {
                   static $currentId = null;
                   static $foo;              // braucht keinen Init, denn:
                
                   if ($id != $currentId) {  // dies passiert auch beim ersten Aufruf!
                      $foo = [];             // "Zurücksetzen"
                      $currentId = $id;
                   }
                   
                   // tu, was mit $foo und $betrag auch immer zu tun ist
                }
                

                Aber ich stochere hier im Nebel. Weil Du ein Datenbeispiel zeigst und Code, der dazu nicht passt, und nicht formal beschreibst, was zu tun ist, mit welchen Daten zu arbeiten ist und wie diese Daten strukturiert sind (inbesondere die Frage nach der Sortiertheit der $id Werte). Das Aufschreiben einer genauen Spezifikation dessen, was zu tun ist, ohne Rücksicht auf PHP, könnte Dir bereits deutlich machen, wie Du programmieren musst.

                Rolf

                --
                sumpsi - posui - obstruxi
                1. Hallo Rolf,

                  danke fürs 'drauf einlassen'.

                  Ich verstehe nicht, warum Du das tun willst. Ich verstehe auch nicht, warum Du $i als Index für das Array nimmst. Wenn Du pro $id Werte aufsummieren willst, müsste dann nicht $id der Index sein? $i scheint mir völlig unerheblich für die Summierung. Zumindest dann, wenn ich dein Beispiel anschaue.

                  Ja, da hatte ich einen Fehler drin.
                  Habe ich auch erst vorhin gemerkt.
                  Die innere Schleife war falsch. Ich habe sie dann durch ein paar Einzelaufrufe ersetzt, erst danach machte $i wieder Sinn, weil ich durch die Einzelaufrufe mehrfach dasselbe $i verwenden konnte und auch sollte.

                  Mit der Zusatzvariable meine ich das so:

                  function test($id, $i, $betrag) {
                     static $currentId = null;
                     static $foo;              // braucht keinen Init, denn:
                  
                     if ($id != $currentId) {  // dies passiert auch beim ersten Aufruf!
                        $foo = [];             // "Zurücksetzen"
                        $currentId = $id;
                     }
                     
                     // tu, was mit $foo und $betrag auch immer zu tun ist
                  }
                  

                  Ok, das sind die entscheidenden Zeilen.
                  $currentID muss static sein, darauf war ich nicht gekommen.
                  Und ich wußte nicht, wie man $foo zurücksetzt.

                  Ich habe das nun so für meinen Originalcode umgesetzt und er macht nun genau das, was ich erwartet hatte.

                  Aber ich stochere hier im Nebel. Weil Du ein Datenbeispiel zeigst und Code, der dazu nicht passt, und nicht formal beschreibst, was zu tun ist, mit welchen Daten zu arbeiten ist und wie diese Daten strukturiert sind (inbesondere die Frage nach der Sortiertheit der $id Werte). Das Aufschreiben einer genauen Spezifikation dessen, was zu tun ist, ohne Rücksicht auf PHP, könnte Dir bereits deutlich machen, wie Du programmieren musst.

                  Ich verstehe.
                  Das ist für einen Helfer besonders unglücklich, wenn er nicht nur den Hintergrund nicht kennt, sondern das Hilfskonstrukt auch noch einen Logikfehler enthält. Umso erstaunlicher, dass Du ich so gut im "Nebel" zurecht gefunden hast.
                  Und umso größerer Dank, dass Du Dich soweit auf meinen Vorschlag eingelassen hast, dass ich mit Deiner Hilfe die Lösung für mein Problem umsetzen konnte.

                  Muss auch nicht immer so sein, versprochen. Aber diesmal gings tatsächlich nicht anders. Beim nächsten mal lass ich mich dann auf Deine/Eure Vorgehensweise ein.

                  Diesmal aber hat es mir so viel weiter geholfen, weil ich ehrlich nicht darauf gekommen bin, wie ich abfrage, ob sich $id geändert hat und nicht auf static $currentID gekommen bin. Deshalb finde ich das jetzt besser als eine andere Lösung, die diese Frage einfach umgangen wäre.

                  Gregor

  2. Hallo Gregor,

    für die Klasse ein Beispiel:

    class Accumulator {
       private $values;
    
       function __construct() {
          $this->values = [];
       }
    
       function addAt($index, $betrag) {
          $this->values[$index] = ($this->values[$index] ?? 0) + $betrag;
       }
    
       function getAt($index) {
          return $this->values[$index] ?? 0;
       }
    }
    
    for ($id=1; $id<=5; $id++) {
       $accu = new Accumulator();   // Neuer Akkumulator für neue ID
       for ($i=0; $i<11; $i++) {
          $accu->addAt($i, $i);
       }
       print_r($accu);              // Testausgabe nach der Schleife
    }
    

    Dieses ?? in Zeile 13 und 17 ist der "null coalescing operator". Der Ausdruck $a ?? $b gibt $a zurück, wenn $a ein existierender Wert und nicht NULL ist. Andernfalls wird $b zurückgegeben - das ist bei $a==NULL der Fall und auch beim Zugriff auf ein uninitialisiertes Array-Element. Dadurch wird eine "Undefined offset" Notice beim ersten Verwenden eines Index vermieden, aus meiner Sicht ist PHP Code, der beim Ausführen eine Notice oder gar eine Warning auslöst, schludrig bis fehlerhaft.

    Die reset-Methode habe ich jetzt gar nicht programmiert. Es dürfte zumeist sinnvoller sein, den alten Akkumulator wegzuwerfen und einen neuen zu erzeugen, statt einen bestehenden zu Resetten.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Gregor,

      für die Klasse ein Beispiel:

      class Accumulator {
         private $values;
      
         function __construct() {
            $this->values = [];
         }
      
         function addAt($index, $betrag) {
            $this->values[$index] = ($this->values[$index] ?? 0) + $betrag;
         }
      
         function getAt($index) {
            return $this->values[$index] ?? 0;
         }
      }
      
      for ($id=1; $id<=5; $id++) {
         $accu = new Accumulator();   // Neuer Akkumulator für neue ID
         for ($i=0; $i<11; $i++) {
            $accu->addAt($i, $i);
         }
         print_r($accu);              // Testausgabe nach der Schleife
      }
      

      Dieses ?? in Zeile 13 und 17 ist der "null coalescing operator". Der Ausdruck $a ?? $b gibt $a zurück, wenn $a ein existierender Wert und nicht NULL ist. Andernfalls wird $b zurückgegeben - das ist bei $a==NULL der Fall und auch beim Zugriff auf ein uninitialisiertes Array-Element. Dadurch wird eine "Undefined offset" Notice beim ersten Verwenden eines Index vermieden, aus meiner Sicht ist PHP Code, der beim Ausführen eine Notice oder gar eine Warning auslöst, schludrig bis fehlerhaft.

      Die reset-Methode habe ich jetzt gar nicht programmiert. Es dürfte zumeist sinnvoller sein, den alten Akkumulator wegzuwerfen und einen neuen zu erzeugen, statt einen bestehenden zu Resetten.

      Lieb von Dir, Rolf, dass Du Dir diese Arbeit gemacht hast.

      Bringt mir nur nichts, weil es mich nicht dort abholt, wo ich stehe.

      Du versuchst gerade, einem Fußballer, der den Ball nicht mal stoppen kann, einen Fallrückzieher beizubringen. Wirklich ehrenwert, aber ich fühle mich damit gerade überfordert und es frustriert mich ein bischen.

      Nicht bös sein, Du hast es ja gut gemeint.

      Gregor

      1. Hallo Gregor,

        nach deiner neuen Beschreibung passt das auch gar nicht mehr auf dein Problem, weil Du keine Summierungen nach $id und $i getrennt brauchst.

        Trotzdem - Klassen sind ein großartiges Tool, um Daten zu kapseln und Operationen darauf auszuführen. Sie lösen deutlich weniger Knoten im Hirn aus als Funktionen mit Gedächtnis (static Variable), das auch noch gelegentlich einen Stups (Reset) braucht. Versuch mal, dich in OOP einzulesen.

        Rolf

        --
        sumpsi - posui - obstruxi
  3. Lieber Gregor,

    um Dich da abzuholen, wo Du bist, gehe ich einfach frech davon aus, dass Du Deinen eigenen Code nicht verstehst. Den Beweis dafür lieferst Du, indem Du folgenden Code-Abschnitt mit der Frage garnierst:

    1. Warum endet mein Script in einer Endlosschleife?
    for($id = 1;$id++;$id <= 5) {
    

    Du bist anscheinend noch nicht sicher im Schreiben von for-Schleifen. Die Angaben in der runden Klammer sind für eine Zählschleife (du willst Werte in einem Array abarbeiten, richtig?) immer so:

    for ($zaehler = 0; $zaehler <= 5; $zaehler = $zaehler +1) {
      // tu was, es gibt hier jede Runde was anderes in $zaehler
      // aber $zaehler ist mindestens 0 und höchstens 5!
    }
    

    Gerne auch rückwärts:

    for ($i = 19; $i >= 0; $i = $i -1) {
      // tu was, es gibt hier jede Runde was anderes in $i
      // aber $i ist mindestens 0 und höchstens 19
    }
    

    Übrigens bedeutet $zaehler++ das gleiche wie $zaehler = $zaehler +1, ist also eine verkürzte Schreibweise. Für rückwärts gibt es auch $zaehler--, was den Wert um genau 1 verringert.

    Wenn Du mal in größeren Schritten gehen willst, geht das so:

    for ($i = 19; $i >= 0; $i = $i -5) {
      // erste Runde ist $i bei 19
      // zweite Runde ist $i bei 14
      // ...
      // letzte Runde ist $i bei 4
    }
    

    So, und jetzt ist klar, warum Du in einer Endlos-Schleife gelandet bist. Du hast die Angaben in der runden Klammer vertauscht. Deine Bedingung für das Ausführen der Schleife, also die Angabe zwischen den beiden ;-Zeichen (Semikola) war der Ausdruck $id++. Das kann man auch als $id=$id+1 lesen. Damit ist es eine Wertzuweisung. Das Ergebnis dieser Wertzuweisung ist in jedem Fall eine Zahl, die, wenn sie als Bedingung verstanden werden muss (Du notierst es ja an genau dieser Stelle dafür), wie ein true gilt. Deswegen wird die Schleife (schon wieder) ausgeführt.

    Das hast Du selbst nicht herausgefunden. Das ist also, wo ich dich mit Deinem Wissensstand abholen muss. Und da denke ich, dass Du noch ziemlich am Anfang stehst. Und das ist absolut OK und überhaupt kein Problem. Es sei denn, Du willst mit Gewalt einen Code verwenden, der nach der Auffassung der Leute hier, die sich besser als Du damit auskennen (oder warum fragst Du sonst hier?), aber überhaupt nicht funktionieren kann.

    Um Dir zu helfen, müssen wir genauer verstehen, was Du eigentlich erreichen willst, damit wir Dir besser raten und erklären können. Und ja, Du wirst die Lösung auf jeden Fall verstehen, denn wir besprechen sie ja hier.

    Liebe Grüße

    Felix Riesterer