php8: Fatal error: Uncaught Error: Undefined constant "int" in...
bearbeitet von
Hallo Jörg,
warum zum grundgütigen Geier schaust Du nicht ins Handbuch?
* [each](https://www.php.net/manual/de/function.each) **Funktion**
* [list](https://www.php.net/manual/de/function.list) **Sprachkonstrukt**
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 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.
Diesen Teil 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.
~~~php
$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:
~~~php
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
~~~php
foreach ($this->images as &$info) // <-- REFERENZ!!!
{
$info['n'] = $this->n;
...
}
~~~
_Rolf_
--
sumpsi - posui - obstruxi
php8: Fatal error: Uncaught Error: Undefined constant "int" in...
bearbeitet von
Hallo Jörg,
warum zum grundgütigen Geier schaust Du nicht ins Handbuch?
* [each](https://www.php.net/manual/de/function.each) **Funktion**
* [list](https://www.php.net/manual/de/function.list) **Sprachkonstrukt**
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.
each liefert 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 si weiter.
Diesen Teil bildet foreach nach. Aber each setzt, bevor es zurückkehrt, den Arrayzeiger auch noch um 1 weiter, 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.
~~~php
$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:
~~~php
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
~~~php
foreach ($this->images as &$info) // <-- REFERENZ!!!
{
$info['n'] = $this->n;
...
}
~~~
_Rolf_
--
sumpsi - posui - obstruxi