Üreteç fonksiyonları, dizi döndüren fonksiyonlara benzerler. Fakat birer iteratör (iterator) gibi davranırlar.
Üreteçlerde işlev tamamen sonlanana kadar ara değerler elde etmemiz gerekir. Üreteç fonksiyonları içinde, ara değer döndürmek için return
anahtar kelimesi kullanılmaz. Bunu sağlayacak anahtar kelime yield
oluyor. yield
keyword’ü sayesinde fonksiyonun state’i ve yığındaki (stack) yeri korunur.
Üreteç fonksiyonunun üretmesi gereken bir sonraki değer lazım olduğunda duraklatıldığı yerden çalmaya devam eden müzik misali değer üretmeye devam eder. Tabii ki işlev içindeki akış, yield
satırına değil de bir return
satırına vardığında ya da işlevin sonuna gelindiğinde üreteç son defa çalışmış olur.
Bir üreteç fonksiyonu çağrıldığında dahili Generator
sınıfından örneklenmiş bir nesne döner. Bu nesne Iterator
arayüzünü implemente eder. Ama Generator
sınıfını new
keyword’ü ile örnekleyemeyeceğimizi unutmamamız gerekir. Generator
sınıfı üreteç fonksiyonlarına özeldir.
<?php // Tanimlama: function generateNumbers($limit) { echo 'Basladi' . PHP_EOL; $i = 0; while (true) { if ($i > $limit) { echo 'Bitti' . PHP_EOL; return; // Burada 'break' de aynı sonucu verecekti } echo 'Ara deger verildi: ' . $i . PHP_EOL; yield $i; $i++; } } // Kullanim: foreach (generateNumbers(5) as $value) { echo 'Ara deger alindi: ' . $value . PHP_EOL; }
yield Keyword’ü Kullanımı
yield
anahtar kelimesi;
<?php function myGenerator() { // ... yield $value; // ... }
şeklinde kullanılırsa,
<?php foreach (myGenerator() as $key => $value) { // ... }
şeklindeki bir döngüde $key
değişkeni her iterasyonda birer artan sıralı tamsayılar ile doldurulacaktır.
<?php function myGenerator() { // ... yield $key => $value; // ... }
şeklinde kullanılırsa,
<?php foreach (myGenerator() as $key => $value) { // ... }
şeklindeki bir döngüde $key
değişkeni, yield
ile elde edilen anahtar değeri ile doldurulacaktır.
yield
değer enjeksiyonu için de kullanılabilir. Bunun için Generator
sınıfının send()
metoduna ihtiyaç duyulur.
<?php // Tanimlama: function generateNumbers($limit) { echo 'Basladi' . PHP_EOL; $i = 0; while (true) { if ($i > $limit) { break; } echo 'Ara deger verildi: ' . $i . PHP_EOL; $request = (yield $i); if (-1 === $request) { echo 'Bitti' . PHP_EOL; return; } $i++; } echo 'Bitti' . PHP_EOL; } // Kullanim: $myGenerator = generateNumbers(5); foreach ($myGenerator as $value) { if (3 === $value) { $myGenerator->send(-1); } }