Generator'lar ve Iterator'lar
Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 62 / 91.
Generator'lar, tam Iterator arayüzünü uygulamaya gerek kalmadan iterator'lar oluşturmak için basit bir yol sağlar. Bir generator fonksiyonu, değerleri teker teker üretmek için return yerine yield kullanır ve her değer arasında yürütmeyi duraklatır.
İşte bir sayı dizisi üreten temel bir generator:
<?php
function countTo(int $max): Generator {
for ($i = 1; $i <= $max; $i++) {
yield $i;
}
}
foreach (countTo(3) as $number) {
echo "$number\n";
}
Çıktı:
1
2
3Temel avantaj bellek verimliliğidir. Bellekte tüm bir dizi oluşturmak yerine, generator'lar değerleri talep üzerine üretir. Bu, büyük veri kümeleriyle çalışırken çok önemlidir; bir milyon kaydı işleyen bir generator, on kaydı işleyenle aynı miktarda bellek kullanır.
Üreteçler ayrıca anahtar-değer çiftleri de üretebilir:
<?php
function userGenerator(): Generator {
yield 'admin' => 'Alice';
yield 'editor' => 'Bob';
}
foreach (userGenerator() as $role => $name) {
echo "$role: $name\n";
}
Çıktı:
admin: Alice
editor: BobKendi sınıflarınızı foreach ile yinelenebilir hale getirmek için Iterator arayüzünü uygulayın. Ancak çoğu durumda, üreteçler (generators) daha az hazır kod (boilerplate) ile daha temiz bir çözüm sunar. Bir sınıfın her şeyi aynı anda belleğe yüklemeden bir öğe koleksiyonunu sunması gerektiğinde, OOP'de özellikle yararlıdırlar.
Görev
KolayHer şeyi aynı anda belleğe yüklemeden büyük koleksiyonlar üzerinde verimli bir şekilde gezinmek için generator'ları kullanan bir ürün envanter sistemi oluşturalım. Ürünleri saklayan ve bunlar üzerinde farklı şekillerde gezinmek için generator metotları sağlayan bir sınıf oluşturacaksınız.
Kodunuzu üç dosya halinde düzenleyeceksiniz:
Product.php— Envanterdeki bir öğeyi temsil eden birProductsınıfı oluşturun. Genel bir$sku(string), genel bir$name(string) ve genel bir$price(float) tanımlamak için constructor promotion kullanın.Inventory.php— Bir ürün koleksiyonunu yöneten ve bunlar üzerinde gezinmek için generator metotları sağlayan birInventorysınıfı oluşturun. Product dosyasını dahil edin. Sınıf şunları yapmalıdır:- Ürünleri saklamak için özel (private) bir dizi özelliğine sahip olmalıdır
- Koleksiyona bir ürün ekleyen bir
addProduct(Product $product)metoduna sahip olmalıdır - Her bir ürünü teker teker döndüren (yield) bir
allProducts(): Generatorgenerator metoduna sahip olmalıdır - Yalnızca fiyatı verilen minimum fiyata eşit veya daha yüksek olan ürünleri döndüren, anahtarın SKU ve değerin ürün olduğu anahtar-değer çiftleri üreten bir
expensiveProducts(float $minPrice): Generatorgenerator metoduna sahip olmalıdır
main.php— Inventory dosyasını dahil edin. Bir girdi alacaksınız: bir minimum fiyat eşiği.Bir
Inventoryoluşturun ve şu üç ürünü ekleyin:- SKU:
"A001", İsim:"Laptop", Fiyat:999.99 - SKU:
"A002", İsim:"Mouse", Fiyat:29.99 - SKU:
"A003", İsim:"Monitor", Fiyat:349.99
Önce,
allProducts()üzerinde gezinin ve her ürünün adını kendi satırına yazdırın.Ardından boş bir satır yazdırın ve ardından girdi eşiğini kullanarak
expensiveProducts()üzerinde gezinin. Her pahalı ürün için kendi satırına"[sku]: [name] - $[price]"yazdırın. Fiyatı tam olarak 2 ondalık basamakla biçimlendirin.- SKU:
Bu görev, generator'ların koleksiyonlar üzerinde tembelce (lazily) gezinmenize nasıl olanak tanıdığını gösterir — her ürün yalnızca istendiğinde üretilir, bu da bu yaklaşımı büyük envanterler için bellek açısından verimli hale getirir. expensiveProducts() içindeki anahtar-değer üretimi, generator'ların yapılandırılmış yineleme verilerini nasıl sağlayabileceğini gösterir.
Kopya kağıdı
Üreteçler (Generators), return yerine yield kullanarak yineleyiciler (iterators) oluşturmanın bellek açısından verimli bir yolunu sunar. Değerleri her seferinde bir tane üretirler ve her değer arasında yürütmeyi duraklatırlar.
Temel üreteç fonksiyonu:
<?php
function countTo(int $max): Generator {
for ($i = 1; $i <= $max; $i++) {
yield $i;
}
}
foreach (countTo(3) as $number) {
echo "$number\n";
}
Üreteçler anahtar-değer çiftleri üretebilir:
<?php
function userGenerator(): Generator {
yield 'admin' => 'Alice';
yield 'editor' => 'Bob';
}
foreach (userGenerator() as $role => $name) {
echo "$role: $name\n";
}
Ana avantaj bellek verimliliğidir - üreteçler, tüm dizileri bellekte oluşturmak yerine değerleri talep üzerine üretirler. Bu, özellikle OOP bağlamlarında büyük veri kümeleri veya koleksiyonlarla çalışırken kullanışlıdır.
Kendin dene
<?php
require_once 'Inventory.php';
// Girdiyi oku
$minPrice = floatval(trim(fgets(STDIN)));
// TODO: Bir Inventory örneği oluşturun
// TODO: Üç ürün ekleyin:
// SKU: "A001", Name: "Laptop", Price: 999.99
// SKU: "A002", Name: "Mouse", Price: 29.99
// SKU: "A003", Name: "Monitor", Price: 349.99
// TODO: allProducts() üzerinde dönün ve her ürünün adını yazdırın
// TODO: Boş bir satır yazdırın
// TODO: $minPrice kullanarak expensiveProducts() üzerinde dönün
// Her pahalı ürün için "[sku]: [name] - $[price]" yazdırın
// Fiyatı tam olarak 2 ondalık basamakla formatlayın
?>Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesneler$this Anahtar KelimesiMetotlarÖzelliklerYapıcı Metot (__construct)Yıkıcı Metot (__destruct)Özet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımparent:: Anahtar KelimesiMetot Geçersiz Kılmafinal Anahtar KelimesiSoyut SınıflarÖzet - Çalışan Hiyerarşisi7Kapsülleme
Public, Protected, PrivateErişim Belirleyicilere Derinlemesine BakışGetter ve Setter MetotlarıBilgi GizlemeConstructor Promotion (8.0)Özet - Öğrenci Kayıt Sistemi10İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımDependency InjectionAnonim SınıflarEnum'lar (PHP 8.1)Fiber'lar (PHP 8.1)Nesne Klonlama: Derinlemesine İncelemeGenerator'lar ve Iterator'lar13Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit KalıbıRepository Kalıbı2İsim Alanları ve Autoloading
İsim Alanlarına Girişuse Anahtar KelimesiPSR-4 Autoloading StandartıComposer AutoloaderÖzet - Düzenli Proje5Arayüzler ve Sözleşmeler
Arayüzlere GirişArayüzleri UygulamaBirden Fazla Arayüz UygulamaArayüz vs Soyut SınıfArayüzler ile Tip BelirlemeÖzet - Şekil Hesaplayıcı8Sihirli Metotlar
Sihirli Metotlara Giriş__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Nesne Klonlama__serialize & __unserializeÖzet - Özel Koleksiyon3Sınıf Özellikleri
Örnek ve Statik ÖzelliklerSınıflarda SabitlerStatik Metotlar ve ÖzelliklerPrivate ve Protected ÖzelliklerReadonly Özellikler (PHP 8.1)Özet - Banka Hesabı Yöneticisi6Çok Biçimlilik
Metot Geçersiz Kılmaya Yeniden BakışArayüzler ile Çok BiçimlilikType Hinting ve Union TypesLate Static BindingÖzet - Ödeme İşlemcisi9Trait'ler
Trait'lere GirişÇoklu Trait KullanımıTrait Çakışma ÇözümüTrait'lerde Soyut MetotlarTrait'ler ve Kalıtım12Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıObserver KalıbıStrategy Kalıbı15Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi