PHP'de Generator ve Iterator Arasındaki Temel Farklar

Sayfayı kopyala
PHP'de Generator'lar (Üreteçler) ve Iterator'lar (Yineleyiciler), özel yineleme mekanizmaları oluşturmak için kullanılan güçlü araçlardır. Ancak, bu iki yapı arasında hem implementasyon hem de çalışma mantığı açısından önemli farklar bulunur.
💡 Özet (TL;DR):
- Generators (Üreteçler):
yieldanahtar kelimesini kullanan, durumu (state) otomatik olarak saklayan hafif fonksiyonlardır. Büyük veri kümeleri için son derece bellek dostudur.- Iterators (Yineleyiciler):
Iteratorarayüzünü (interface) uygulayan ve 5 adet zorunlu lifecycle metodunu barındıran sınıflardır. Geriye sarılabilirler (rewindable) ve tam kontrol sağlarlar ancak daha fazla kod yazımı gerektirirler.- Temel Seçim Kriteri: Basit ve bellek tasarruflu veri akışları için (örn. devasa CSV okumak) Generator kullanın. Özel nesne durum yönetimi veya döngüyü başa sarabilme (rewind) ihtiyacınız varsa Iterator sınıfı tercih edin.
Öncelikle bu kavramların ne anlama geldiğini tanımlayalım. Bir Generator, geliştiricinin belirli bir değer kümesi üzerinde yineleme yapmak için kullanabileceği hafif bir yineleyici oluşturmasını sağlayan özel bir fonksiyondur. Generator'lar, fonksiyonun yürütülmesini geçici olarak duraklatmasına ve çağırıcıya bir değer dönmesine olanak tanıyan yield anahtar kelimesi kullanılarak oluşturulur. Fonksiyon daha sonra kaldığı yerden devam edebilir.
Diğer taraftan bir Iterator, PHP'deki yerleşik Iterator arayüzünü (interface) uygulayan bir nesnedir (object). Bu arayüz, bir sınıfın yineleyici olarak kabul edilmesi için mutlaka uygulanması gereken metotları tanımlar. Bu metotlar; rewind, current, key, next ve valid şeklindedir ve geliştiriciye yineleme süreci üzerinde tam kontrol sunar.
Kod Örnekleri ile Karşılaştırma
Farkı daha iyi anlamak için, 1'den 1.000.000'a kadar olan sayıları üreten bir yapıyı her iki yöntemle de kuralım.
1. Özel Bir Iterator Sınıfı Kullanmak
Iterator arayüzünü uygulamak için bir sınıf oluşturmamız ve 5 adet metodu tanımlamamız gerekir:
class RangeIterator implements Iterator {
private int $start;
private int $end;
private int $current;
public function __construct(int $start, int $end) {
$this->start = $start;
$this->end = $end;
}
public function rewind(): void {
$this->current = $this->start;
}
public function current(): mixed {
return $this->current;
}
public function key(): mixed {
return $this->current;
}
public function next(): void {
$this->current++;
}
public function valid(): bool {
return $this->current <= $this->end;
}
}
// Kullanım
$range = new RangeIterator(1, 1000000);
foreach ($range as $number) {
// Sayıyı işle
}
2. Generator Fonksiyonu Kullanmak
Aynı işlevselliği, yield kullanarak tek bir fonksiyonla çok daha az kod yazarak sağlayabiliriz:
function rangeGenerator(int $start, int $end) {
for ($i = $start; $i <= $end; $i++) {
yield $i;
}
}
// Kullanım
$range = rangeGenerator(1, 1000000);
foreach ($range as $number) {
// Sayıyı işle
}
Her iki yöntem de O(1) bellek karmaşıklığı ile çalışır; yani 1.000.000 sayının tamamını aynı anda hafızaya yüklemezler. Ancak, Generator versiyonu çok daha az boilerplate (şablon) kod gerektirir.
Detaylı Farklar
Generator'lar ve Iterator'lar arasındaki temel farklardan biri nasıl uygulandıklarıdır. Generator'lar basit bir fonksiyon sözdizimi ile oluşturulurken, Iterator'lar bir sınıf içinde arayüz uygulanarak oluşturulur. Bu, Generator'ların yazılmasını ve okunmasını son derece kolaylaştırır. Ancak Iterator'lar, tüm lifecycle metotlarını elinizle yazmanıza izin verdiği için yineleme süreci üzerinde daha fazla esneklik ve kontrol sağlar.
Diğer bir fark ise kullanım şekilleridir. Generator'lar, herhangi bir iterable nesne gibi doğrudan foreach döngüsünde kullanılabilir ve oldukça pratiktir. Iterator'lar ise gerektiğinde döngü metodları (next(), current()) manuel olarak çağrılarak daha hassas akış kontrolleri yapılmasına imkan tanır.
Özellik Karşılaştırma Tablosu
| Özellik | Generators | Iterators |
|---|---|---|
| Sözdizimi (Syntax) | yield içeren fonksiyon | Iterator arayüzünü uygulayan sınıf |
| Kod Yoğunluğu (Boilerplate) | Çok az | Fazla (5 metot zorunludur) |
| Hafıza Tüketimi (Memory) | Düşük (O(1)) | Düşük (O(1)) |
| Başa Sarılabilme (Rewind) | Hayır (Kapatıldıktan sonra geri sarılamaz) | Evet (rewind() metodu desteklenir) |
| Durum Yönetimi (State) | PHP motoru tarafından otomatik yönetilir | Sınıf özellikleri üzerinden manuel yönetilir |
Sıkça Sorulan Sorular (FAQ)
- PHP'de bir Generator başa sarılabilir (rewind) mi?
- Hayır. Bir generator fonksiyonu bir kez çalışıp sonlandığında veya kapatıldığında geri sarılamaz. Aynı generator nesnesini ikinci kez
foreachiçinde döndürmeye çalışırsanız hata alırsınız. Tekrar yinelemek için generator fonksiyonunu yeniden çağırıp yeni bir Generator nesnesi üretmelisiniz.
- Hayır. Bir generator fonksiyonu bir kez çalışıp sonlandığında veya kapatıldığında geri sarılamaz. Aynı generator nesnesini ikinci kez
- Ne zaman bir Generator yerine özel bir Iterator sınıfı tercih etmeliyim?
- Eğer yineleme nesnesine ek iş mantığı (business logic) eklemeniz gerekiyorsa, yineleme durumu çok fazla özel değişkene bağlı ve karmaşıksa veya döngünün birden fazla kez geriye sarılıp tekrar çalıştırılması gerekiyorsa (data source'u yeniden oluşturmadan) bir
Iteratorsınıfı yazmak daha doğru bir yaklaşımdır.
- Eğer yineleme nesnesine ek iş mantığı (business logic) eklemeniz gerekiyorsa, yineleme durumu çok fazla özel değişkene bağlı ve karmaşıksa veya döngünün birden fazla kez geriye sarılıp tekrar çalıştırılması gerekiyorsa (data source'u yeniden oluşturmadan) bir
Resmi Dokümantasyonlar ve Kaynaklar
Sonuç olarak, hem Generator'lar hem de Iterator'lar PHP'de özel yineleme akışları oluşturmak için harika araçlardır. Seçiminiz, projenizin karmaşıklığına ve geriye sarılabilirlik gibi spesifik ihtiyaçlarına göre şekillenmelidir.
Bu Yazıda Yapılan Değişiklikler
- 20.06.2026: Yazı ilk kez yayınlandı (karşılaştırmalı kod örnekleri, tablo ve LLO geliştirmeleri ile birlikte).
