Rolf B: php8: Fatal error: Uncaught Error: Undefined constant "int" in...

Beitrag lesen

Hallo Jörg,

warum zum grundgütigen Geier schaust Du nicht ins Handbuch?

Das löst man heute mit foreach($array as $key => $value), da hast Du recht.

Die each-Funktion hat aber eine Besonderheit, die foreach nicht hat: den Arrayzeiger. Mit reset($array) setzt man ihn auf das "erste" Element - was das erste Element ist, wird durch die zeitliche Reihenfolge bestimmt, in der die Elemente ins Array gekommen sind. Per Default steht der Arrayzeiger auf dem ersten Element, deswegen findest Du bei Dir vielleicht kein reset, wenn das Array nur ein einziges mal durchlaufen (durcheacht?) wird.

each liefert zu dem Arrayelement, auf das der Arrayzeiger verweist, ein Array mit 4 Einträgen. Diese haben die Schlüssel 1, "value", 0 und "key", in dieser Reihenfolge. Das list-Sprachkonstrukt sucht in diesem Array nach den numerischen Schlüsseln und weist sie den entsprechenden Variablen zu, die list übergeben werden. Die erste Variable bekommt Index 0, die zweite den Index 1, und so weiter. Ingesamt ist das eine wüste Kopiererei und es ist ganz gut, dass das missbilligt wird.

Das Ermitteln von $file und $info bildet foreach nach. Aber each setzt, bevor es zurückkehrt, den Arrayzeiger auch noch auf die nächste Position, während foreach den Arrayzeiger komplett ignoriert.

Solange Du also eine Schleife hast, wo vor der Schleife der Arrayzeiger mit reset zurückgesetzt wird, und in/nach der Schleife nicht irgendwas passiert, was Bezug auf den Arrayzeiger nimmt, kannst Du es durch foreach ersetzen. In der gezeigten Schleife sieht das ganz gut aus.

Aber mit foreach kannst Du etwas machen, was mit list/each nicht geht: Die Infos im Images-Array verändern. In $info scheint ja jeweils ein Array mit Informationen zum Image zu stehen, und du musst ein 'n' hinzufügen und ein 'data' entfernen. Dafür kannst Du nicht $info verwenden, weil PHP diesen "copy on write" Mechanismus für Arrays hat, die einer anderen Variable zugewiesen werden.

$a = [ 1, 2, 3]; // ein Array
$b = $a;         // Array wird NICHT kopiert, $b zeigt auf das Array in $a

$b[4] = 17;      // JETZT wird erstmal kopiert, dann die 17 ergänzt

// Neuer Versuch, mit Referenz
$b &= $a;        // Array wird NICHT kopiert, $b zeigt auf das Array in $a

$b[4] = 17;      // $b ist eine Referenz, es wird NICHT kopiert, 
                 // $a und $b zeigen weiterhin auf's gleiche Array.

Der list($key, $info) = each($images) Mechanismus erzeugt keine Referenz, deswegen führen Änderungen an $info dazu, dass eine Kopie entsteht und Du musst mit $images[$key] rumfummeln.

Mit foreach dagegen geht es so:

foreach ($this->images as $file => &$info)
{
   $info['n'] = $this->n;
   ...
}

Siehst Du das & hinter dem =>? Damit erzeugt die foreach-Schleife eine Referenz auf den Array-Inhalt und Änderungen sind möglich.

Achso, $file brauchst Du dann ja gar nicht mehr 😀. Damit reicht

foreach ($this->images as &$info)   // <-- REFERENZ!!!
{
   $info['n'] = $this->n;
   ...
}

Rolf

--
sumpsi - posui - obstruxi