Start · Sprachen · PHP · Referenz · iterator_apply

iterator_apply

Funktion

Ruft eine Benutzerfunktion für jedes Element eines Iterators auf und gibt die Anzahl der iterierten Elemente zurück.

seit PHP 5.1.0 Kategorie: oop

Signatur

iterator_apply(Traversable $iterator, callable $function, ?array $extra = null): int

Beschreibung

iterator_apply() ist das Iterator-Pendant zu array_walk(): Sie durchläuft jeden Schritt eines Traversable-Objekts und ruft dabei die übergebene $function auf. Solange die Callback-Funktion true zurückgibt, wird die Iteration fortgesetzt; gibt sie false zurück, bricht die Funktion vorzeitig ab.

Der Callback erhält den Iterator selbst als erstes Argument, gefolgt von optionalen zusätzlichen Parametern aus dem Array $extra. Über $iterator->current(), $iterator->key() usw. kann der Callback auf das aktuelle Element zugreifen. Dieses Muster vermeidet das Erzeugen eines temporären Arrays und ist daher besonders speicherschonend bei großen oder unendlichen Datenquellen.

Typische Einsatzfelder sind das Transformieren, Validieren oder Protokollieren von Elementen aus Dateisystem-Iteratoren (DirectoryIterator, RecursiveIteratorIterator), Datenbankresultaten oder selbst implementierten Generatoren, ohne den gesamten Datensatz zunächst in ein Array laden zu müssen.

Im Unterschied zu einer einfachen foreach-Schleife erlaubt iterator_apply() das Weitergeben von Kontextvariablen über $extra und kann durch den Rückgabewert des Callbacks kontrolliert abgebrochen werden, was z. B. bei Suchabbrüchen nützlich ist.

Parameter

Name Typ Default Beschreibung
$iterator Pflicht Traversable Der Iterator oder ein beliebiges Traversable-Objekt, dessen Elemente durchlaufen werden sollen.
$function Pflicht callable Callback-Funktion, die für jedes Element aufgerufen wird. Sie erhält den Iterator als erstes Argument. Gibt sie false zurück, wird die Iteration abgebrochen; true setzt sie fort.
$extra array|null null Optionales Array mit zusätzlichen Argumenten, die nach dem Iterator an den Callback übergeben werden. Nützlich, um Kontextdaten wie Logger-Objekte oder Zähler ohne globale Variablen einzuschleusen.

Rückgabewert

Typ
int
Beschreibung
Gibt die Anzahl der tatsächlich iterierten Elemente zurück. Wird die Iteration durch den Callback vorzeitig abgebrochen (Rückgabe false), entspricht der Wert der Anzahl der bis zum Abbruch verarbeiteten Elemente.

Beispiele

Alle Dateien eines Verzeichnisses ausgeben

<?php
$directory = new DirectoryIterator(__DIR__);

$count = iterator_apply(
    $directory,
    function (DirectoryIterator $iter): bool {
        if (!$iter->isDot()) {
            echo $iter->getFilename() . PHP_EOL;
        }
        return true; // Iteration fortsetzen
    },
    [$directory]
);

echo "Gesamt iterierte Einträge: $count" . PHP_EOL;
index.php README.md ... Gesamt iterierte Einträge: 5

Früher Abbruch bei erstem Treffer

<?php
$data = new ArrayIterator([10, 25, 3, 47, 8]);
$found = null;

$iterated = iterator_apply(
    $data,
    function (ArrayIterator $iter) use (&$found): bool {
        $value = $iter->current();
        if ($value > 40) {
            $found = $value;
            return false; // Abbruch
        }
        return true;
    },
    [$data]
);

echo "Iterierte Elemente bis zum Fund: $iterated" . PHP_EOL;
echo "Gefundener Wert: $found" . PHP_EOL;
Iterierte Elemente bis zum Fund: 4 Gefundener Wert: 47

Kontextdaten über $extra weitergeben

<?php
$numbers = new ArrayIterator([1, 2, 3, 4, 5]);
$log = [];

iterator_apply(
    $numbers,
    function (ArrayIterator $iter, array &$log): bool {
        $log[] = 'Verarbeite: ' . $iter->current();
        return true;
    },
    [$numbers, &$log]
);

print_r($log);
Array ( [0] => Verarbeite: 1 [1] => Verarbeite: 2 [2] => Verarbeite: 3 [3] => Verarbeite: 4 [4] => Verarbeite: 5 )

// Wichtig · Fallstricke

Wichtig: Der Callback muss den Iterator als ersten Parameter akzeptieren – nicht das aktuelle Element direkt. Auf das aktuelle Element wird über $iterator->current() zugegriffen. Das ist ein häufiger Stolperstein beim Umstieg von array_walk().

Vergisst der Callback einen Rückgabewert (implizit null), wird dies als falsy gewertet und die Iteration sofort nach dem ersten Element abgebrochen. Daher immer explizit return true; angeben, wenn die Schleife vollständig durchlaufen soll.

Soll der Iterator nach dem Aufruf erneut verwendet werden, muss er manuell mit rewind() zurückgesetzt werden, da iterator_apply() den internen Zeiger des Iterators verändert.