Probleme mit foreach in PHP

Über Probleme mit Foreach-Schleifen:

Da ich über Wochen einige Stunden am rätseln war, warum eine Funktion mit einer
Foreach-Schleife nicht das tat, was sie sollte, möchte ich euch zeigen, was
diese Schleifen nicht können, oder was man mit ihnen nicht machen darf.

Kurz beschrieben:

Man kann die noch folgende Elemente des in der Foreach verarbeiteten Arrays zwar
verändern, aber diese sind dann noch nicht in der foreach verfügbar.

Das klingt ziemlich kompliziert, deshalb mal ein simples Codebeispiel:


<?php

for($i = 0; $i < 3; $i++) {

$array[$i] = 1;

}

echo ‚In der foreach:<br/>‘;

foreach($array as $id => $wert) {

$array[0]++;

$array[1]++;

$array[2]++;

echo ‚$array[‚.$id.‘] = ‚.$wert.‘ <br />‘;

}

echo ‚Danach:<br/>‘;

echo ‚$array[2] = ‚.$array[2];

?>

Zuerst wird hier ein kleines Array erstellt: Array(0 => 1, 1 => 1, 2 =>
1)

Diese 3 Werte werden dann in der Foreach-Schleife immer um eins erhöht.

Ich erwartete also folgende Ausgabe:

In der foreach:

$array[0] = 2

$array[1] = 3

$array[2] = 4

Danach:

$array[2] = 4

Völlig unerwartet hat mich dann das folgende Ergebnis getroffen:

In der foreach:

$array[0] = 1

$array[1] = 1

$array[2] = 1

Danach:

$array[2] = 4

Das heißt, dass die $wert-Variable aus dem Script den aktuellen Wert des
Elements im Array nicht annimmt, sondern den Wert, den es zu Beginn der foreach
hatte. Wieso?

Meine aktuelle Lösung, die php4 kompatibel ist, sieht so aus:

<?php

for($i = 0; $i < 3; $i++) {

$array[$i] = 1;

}

echo ‚In der foreach:<br/>‘;

foreach($array as $id => $wert) {

$wert = $array[$id];

$array[0]++;

$array[1]++;

$array[2]++;

echo ‚$array[‚.$id.‘] = ‚.$wert.‘ <br />‘;

$array[$id] = $wert;

}
echo
‚Danach:<br/>‘;

echo ‚$array[2] =
‚.$array[2];

?>

Hier lese ich den Wert der $wert-Variable einfach aus dem aktuellen Stand des
Arrays aus und schreibe ihn nach der Operation wieder zurück ins Array; dies
ergibt auch die gewünschte Ausgabe.

Eine andere Lösung für php5 (by Leon Winter) sieht so aus:


<?php

for($i = 0; $i < 3; $i++) {

$array[$i] = 1;

}

echo ‚In der foreach:<br/>‘;

$referenz = &$array;

foreach($referenz as $id => &$wert) {

$array[0]++;

$array[1]++;

$array[2]++;

echo ‚$array[‚.$id.‘] = ‚.$wert.‘ <br />‘;

}

echo ‚Danach:<br/>‘;

echo ‚$array[2] = ‚.$array[2];

?>

Hier wird die Foreach mit einer Referenz auf das Array ausgeführt (dazu das
&-Zeichen); dies ergibt auch die gewünschte Ausgabe.

Ich wusste nicht nur nicht, dass es so ist, ich weis auch nicht warum.

Happy Nerding

Was sehe ich denn da…

Wer auf seinem Netzteil zu kalte Clementinen aufwärmen kann,

img_0023

…der kann auch Tee aus einer definitiv für Kaffee bestimmten Tasse trinken.

img_0102

Die Bademeister

Ich habe leider keine Band. Oder keine Zeit für eine Band. Außer zwei Wochen im Jahr, da bin ich nämlich in Dänemark. So sieht das dann aus…

bademeister_1bademeister_2bademeister_3

Eisblume

Und genau nach dem gleichen Verfahren habe ich noch ein Bild gemalt. Da ich keinen A3-Scanner habe, musste ich halt zwei Scans zusammenfügen.

eisblume_scaneisblume_fotoeisblume_painted

Pullimädel

Ab und zu, in diesem Fall schon länger her, versuche ich mich am Zeichnen. Das läuft so ab, dass ich auf DIN-A3 sehr groß die Konturen male, diese dann einscanne, überarbeite und kleiner (DIN-A4) wieder ausdrucke und ausmale. Am Ende wird wieder eingescannt.

Leider konnte ich zu diesem Zeitpunkt keinerlei Hände so zeichnen, dass es für mich befriedigend aussah. Auch jetzt sind mir Hände häufig noch ein Hindernis…

So sieht der Entwurf mit den Konturen nach dem Scan aus, bzw. die Überarbeitete Version zum Vergleich:

pullimaedel_scanDies, ursprünglich A3, drucke ich kleiner wieder aus und bemale es mit Buntstiften. Viele haben mir schon geraten, diese Comic-Marker zu kaufen, mit denen man gleichmäßige Farben malen kann. Das lohnt sich für mich allerdings nicht, weil ich zu selten zeichne.

Ausgemalt und erneut gescannt:

pullimaedel_paintedSpäter habe ich auch versucht, das Mädel mit dem Computer zu colorieren. Ohne Grafiktablett gestaltet sich das aber für sehr sehr schwierig, ich hab es deshalb abgebrochen.

pullimaedel_colorized

Dr. House

Hatte ich schon erwähnt, dass ich Dr. House-Fan bin?

Dazu musste gleich mal ein Foto geschossen werden.

Die Chroniken eines FSJlers.

Wie die wenigsten wissen, habe ich nach meinem ABI ein Freiwilliges Soziales Jahr an einer Privatschule absolviert.

Was mir dort, obwohl oder weil die Schule ein sehr professionelles Image hat, widerfahren ist, musste ich deshalb dringend schriftlich verfassen.

Die Chroniken eines FSJlers

Foobar vs. Fail

Foobar vs. Fail,Foobar vs. Fail,Foobar vs. Fail, Foobar vs. Fail, Foobar vs. Fail, Foobar vs. Fail, Foobar vs. Fail, Foobar vs. Fail