peat_a: end() in foreach-schleife

Hallo Mitstreiter,
vielen Dank schonmal vorweg, dass sich jemand dieser Frage annimmt. Es geht darum, ob innerhalb einer foreach-schleife mit reset() oder end() überprüft werden kann, ob der erste bzw. letzte Wert des in der foreach-Schleife verwendeten Arrays gerade durchlaufen wird. Hier ein Beispiel:

foreach ($array as $key => $value)
{

if ($value == reset($array))
 {
  echo $value." ist der erste Wert des durchlaufenen Arrays!"
 }

if ($value == end($array))
 {
  echo $value." ist der letzte Wert des durchlaufenen Arrays!"
 }
}

Das Problem könnte auftauchen, weil der interne Zeiger von $array innerhalb der if-Anweisung auf seinen ersten/letzten Wert gesetzt wird und die Schleife also nur einmal oder endlos durchlaufen wird. In php4 funktionert das Konstrukt einwandfrei, aber ich bin mir nicht sicher, ob das auch so dokumentiert ist. Lt. php.net wird in der foreach-schleife nur eine Kopie von $array verwendet, aber der interne Zeiger des originalen Arrays trotzdem bewegt??? Ich bin mir im Klaren darüber, dass es dafür einfache workarounds gibt, aber es würde viel Arbeit verursachen, alle Skripte umzuschreiben. Daher wollte ich vorher wissen, ob es notwendig ist oder nicht. Vielen Dank nochmal im Voraus.
peat_a

  1. Hallo,

    Lt. php.net wird in der foreach-schleife nur eine Kopie von $array verwendet, aber der interne Zeiger des originalen Arrays trotzdem bewegt???

    Wenn du eine Datei kopierst und dann in der Kopie irgendwas veränderst, wird es auch im orginal geändert?

    Das ist doch gerade der Sinn einer Kopie, ansonsten würde man eine Referenz nehmen.

    Grüße
    Jeena Paradies

    1. Tach, Jeena.

      Wenn du eine Datei kopierst und dann in der Kopie irgendwas veränderst, wird es auch im orginal geändert?

      Ja, so steht es zumindest in der Doku:

      "However, the internal pointer of the original array is advanced with the processing of the array. Assuming the foreach loop runs to completion, the array's internal pointer will be at the end of the array."

      Was der Sinn dahinter sein soll, weiß ich auch nicht. Außerdem habe ich dieses Verhalten noch nie beobachten können.

      --
      Once is a mistake, twice is jazz.
      1. Wenn du eine Datei kopierst und dann in der Kopie irgendwas veränderst, wird es auch im orginal geändert?

        Ja, so steht es zumindest in der Doku:

        Das war wohl etwas zu allgemein bejaht und führt vermutlich zu Mißverständnissen. Was ich sagen wollte:

        Laut Doku ändert sich auch der interne Zeiger des Original-Arrays. Wenn du in ...

        foreach($a as $key => $val)

        ... der Variablen $val einen neuen Wert zuweist, ändert sich im Original *nichts*. Dazu müßtest du $a[$key] benutzen.

        --
        Once is a mistake, twice is jazz.
        1. Hallo,

          Hm irgendwie stehe ich auf dem Schlauch und kappiere absolut nicht was du mir sagen willst, bzw. wo das Problem ist ;-)

          foreach() ändert nichts am orginal Array, auch nicht die Position des Zeigers:

          $a = array(1,2,3,4,5,6,7,8,9);  
          foreach($a as $key => $value) echo "current: ".current($a)." | key: ".$key." | value: ".$value."\n";  
          echo "last current: ".current($a);
          

          ergibt:

          current: 1 | key: 0 | value: 1
          current: 1 | key: 1 | value: 2
          current: 1 | key: 2 | value: 3
          current: 1 | key: 3 | value: 4
          current: 1 | key: 4 | value: 5
          current: 1 | key: 5 | value: 6
          current: 1 | key: 6 | value: 7
          current: 1 | key: 7 | value: 8
          current: 1 | key: 8 | value: 9
          last current: 1

          Wenn man natürlich innerhalb von foreach() mit reset() oder end() den Zeiger irgendwo anders hinschiebt, dann ist er natürlich wo anders als am anfang.

          Grüße
          Jeena Paradies

          1. Tach, Jeena.

            Hm irgendwie stehe ich auf dem Schlauch und kappiere absolut nicht was du mir sagen willst, bzw. wo das Problem ist ;-)

            foreach() ändert nichts am orginal Array, auch nicht die Position des Zeigers:

            Das ist es, was ich dir sagen will. :)

            Die *Doku* behauptet allerdings, daß sich der Zeiger im Original ändert. Und das kann ich genauso wenig bestätigen wie du gerade mit deinem Testprogramm.

            --
            Once is a mistake, twice is jazz.
            1. Hi Blaubart und Jeena,

              Die *Doku* behauptet allerdings, daß sich der Zeiger im Original ändert. Und das kann ich genauso wenig bestätigen wie du gerade mit deinem Testprogramm.

              Ich glaube, die Doku stimmt da einfach nicht. Ich habe damit jetzt noch ein bisschen rumprobiert und mit dem Ausgangsarray kann ich einfach machen, was ich will, die Schleife scheint auf das Ausgangsarray überhaupt keinen Einfluss zu nehmen. Bleibt nur zu hoffen, dass das auch in zukünftigen php-Versionen so bleibt.

              Danke nochmal!
              Gruß
              peat_a

          2. Also erstmal vielen Dank für Eure Antworten.

            Ich schließe daraus, dass ich mit dem ursprünglichen Array innerhalb der foreach-Schleife machen kann, was ich will, der Schleifenverlauf wird davon nicht beeinflusst. Ich war mir nur nicht ganz sicher, da die Doku in dem Fall meiner Meinung nach nicht ganz transparent ist. Ich könnte mir aber denken, dass der Prozess der Schleife in etwa so funktioniert:

            Zuerst wird der Zeiger des zu durchlaufenden Arrays auf sein erstes Element gesetzt, dann wird das Array kopiert und danach die Schleife mit der Kopie des Arrays gestartet und durchlaufen. Am Ende steht der Zeiger des Ausgangsarrays dort, wohin er entweder während des Prozesses verschoben wurde oder am Anfang, weil er dorthin am Anfang des Schleifenprozesses gesetzt wurde. Die Kopie des Arrays, die für das Durchlaufen der Schleife verwendet wurde, ist zu keinem Zeitpunkt ansprechbar.

            Danke nochmal, ich denke, dass ich mir eine Menge Arbeit sparen kann...Gruß peat_a

    2. Wenn du eine Datei kopierst und dann in der Kopie irgendwas
      veränderst, wird es auch im orginal geändert?

      Das ist doch gerade der Sinn einer Kopie, ansonsten würde man eine
      Referenz nehmen.

      Oder die andere Variante - wie im Falle des foreach()-Konstrukts -
      wo eine Kopie erstellt wird, damit das eigentliche Array simultan
      bearbeitet werden kann.

  2. Tach, Peter.

    In php4 funktionert das Konstrukt einwandfrei ...

    Tatsächlich? Dann hast du dieser Routine vermutlich noch keine Arrays gefüttert, in denen der gleiche Wert mehrfach vorkommt.

    --
    Once is a mistake, twice is jazz.