PHP – foreach „greift“ nicht, keine Iteration

Kleiner Hinweis: Wenn bei euch eine „foreach“ Schleife nicht greift, obwohl alles richtig zu sein scheint – das array ist da, Werte sind drin, sogar die richtigen 😉 – und trotzdem keine Iteration über das array stattfindet, dann sucht mal vor Ausführung des foreachs nach array-Iterations Funktionen, die das komplette Array durchlaufen, z.B.: array_map, array_walk, usw.

Die Ursache ist: Durch den kompletten Durchlauf des Arrays steht der interne Pointer (wir erinnern uns dunkel, PHP ist in C/C++ geschrieben) immer noch auf dem letzten Element, die foreach-Schleife kann also nicht loslaufen, weil Sie – rein technisch – schon am Ende ist und „überspringt“ das foreach.

Die Lösung ist trivial: Nach der Iterationsfunktion oder direkt vor dem foreach setzt ihr

reset($myArray);

Das reset setzt euer Array intern wieder auf das erste Element und schon funktioniert eure foreach-Schleife wieder – die C/C++ und Java-Entwickler kennen das Problem 😉

6 Gedanken zu „PHP – foreach „greift“ nicht, keine Iteration

  1. Fabian

    Das widerspricht meinen Erfahrungen und auch dem was im Handbuch steht. Das Verhalten an sich kenne ich auch nur von while in Kombination mit list() und each()

    Kleiner Test:

    < ?php $array = array(1, 2, 3, 4, 5); end($array); while (list(,$element) = each($array)) { echo "while: " . $element . "\n"; } foreach ($array as $element) { echo "foreach: " . $element . "\n"; }

    Ergebnis:

    while: 5
    foreach: 1
    foreach: 2
    foreach: 3
    foreach: 4
    foreach: 5

    Hier auch nochmal der Auszug aus dem Handbuch:

    When foreach first starts executing, the internal array pointer is automatically reset to the first element of the array. This means that you do not need to call reset() before a foreach loop.

    Handelt es sich dabei um ein echtes Array oder um ein Objekt das sich wie ein Array verhält?

    Antworten
    1. Sascha Presnac Beitragsautor

      @Fabian: Generell stimme ich dir zu, dein Testcode funktioniert auch problemlos. Leider funktioniert das foreach auf dem Kundenserver nur dann, wenn ich das reset davorschreibe, ansonsten startet die Schleife nicht. Gleicher Code bei mir lokal funktioniert auch ohne – deswegen war der Fehler auch so schwer zu finden. Woran das nun genau liegt versuche ich nächste Woche mal rauszufinden.

      Antworten
      1. Jannik

        Wenn man selbst den Iterator implementiert, sollte man die Implementierung von rewind() nicht leer lassen.
        Aber ich kann bestätigen, was Fabian gesagt hat.

        Man sehe sich nur das Beispiel hier an: http://de3.php.net/manual/en/class.iterator.php

        Die Reihenfolge ist:
        string(18) „myIterator::rewind“
        string(17) „myIterator::valid“
        string(19) „myIterator::current“
        string(15) „myIterator::key“
        int(0)
        string(12) „firstelement“

        Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.