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.

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