Kaynak: http://www.kirlibit.com/php-generator-nedir/

PHP 5.5 ile birlikte eklenmiş olan "php generator" özelliğine değineceğiz.

PHP Generator çok büyük sayıdaki döngüleri daha hızlı ve daha az kaynak tüketerek oluşturmamıza yarıyor. Şöyle ki; Yüklü işlemlerin yapılacağı bir betik yazmanız gerekiyor, Örneğin betiğimiz girilen değer kadar saysın.


function saydir($s = 10) {
$dizi = [];

for ($i = 1; $i < $s; $i++) {
$dizi[] = $i;
}

return $dizi;
}

foreach (saydir(15) as $s) {
echo "Sayı {$s}";
}


Aldığımız çıktı

Sayı 1
Sayı 2
Sayı 3
Sayı 4
Sayı 5
Sayı 6
Sayı 7
Sayı 8
Sayı 9
Sayı 10
Sayı 11
Sayı 12
Sayı 13
Sayı 14
Sayı 15


Peki biz bu işlemi PHP_INT_MAX (2147483647) gibi büyük bir sayı üzerinde yapmaya çalışsaydık? Tabii ki sonuç; php bize belleğin yetersiz belirten hata mesajı gösterecekti. Betiğin çalışması için mecburen belleği php.ini dosyamızdan artırmak durumunda kalacaktık, ancak sizce bu olması gereken bir çözüm mü? sadece bir fonksiyonun çalışması için tüm çalışacak tüm php betiklerinin ayarını değiştirmek ne derece sağlıklı olur? tabi ki olmaz, burada php generator devreye giriyor. Aynı fonksiyonu php generator kullanarak yaparsak şöyle olacak;


function saydir($s = 10) {
for ($i = 1; $i < $s; $i++) {
yield $i;
}
}

foreach (saydir(PHP_INT_MAX) as $s) {
echo "Sayı {$s}
";
}


Ne Değişti?
Betiğimiz sorunsuz şekilde çalıştı, yield gerektiğinde değeri döndürdü, ilk fonksiyonda yaptığımız tüm diziyi bellekte tutma, daha sonra bunu döndürme işlemindeki gereksiz kaynak kullanımının önüne geçti.

Peki verimizin anahtar-değer şeklinde dönmesi gerekiyorsa?
Mesela saydığı sayı ile birlikte bir de rasgele sayı döndürmesi gerekiyorsa.


function saydir($s = 10) {
for ($i = 1; $i < $s; $i++) {
$deger = ($i*mt_rand());

yield $i => $deger;
}
}

foreach (saydir(PHP_INT_MAX) as $s => $d) {
echo "Sayı {$s}, Rasgele sayı {$d}
";
}


Yukarıda gördüğünüz gibi tıpkı dizilerde anahtar-değer ilişkisini kurduğumuz gibi, yield'e değer veriyoruz.

Peki biz bu işlemin belirli bir sayıdan sonra durmasını istiyorsak ne yapmalıyız?

function saydir($s = 10) {
for ($i = 1; $i < $s; $i++) {
$komut = ( yield $i => ($i*mt_rand()) );

if($komut == 'dur'){ return; }
}
}


foreach (saydir(PHP_INT_MAX) as $s => $d) {
if($s == 10000){ $s->send('dur'); }

echo "Sayı {$s}, Rasgele sayı {$d}
";
}


Yukarıdaki örnekte 10.000'e gelince yield'e geri değer göndererek durmasını emrettik.

PHP generator kullanmanız için illaki verinizin büyük olması gerekmiyor, php generator size hızı ve daha az kaynak kullanmayı sunuyor. Unutmayın bu özelliği sadece fonksiyon içerisinde kullanabilirsiniz. Burada verdiğimiz örnekler herkesin anlaması için basit örneklerdir, kullanacağınız yer bir xml botu, bir hata kayıt dosyası, bir txtdeki tüm satırları yakalayan betik olabilir, size, foreach içinde yaptığınız işlemlerden daha fazla hız ve daha az kaynak kullanımı sunacaktır.

Herkese iyi çalışmalar diliyorum.