บทนำ
เมื่อเรียก Generator Function ภายในจะคืน Object ของ Class Generator ซึ่ง Implement Iterator Interface Interface Iterator กำหนด Abstract Methods 5 ตัว:
- Iterator::current - คืนค่า Element ปัจจุบัน
- Iterator::key - คืนค่า Key ของ Element ปัจจุบัน
- Iterator::next - เลื่อนไป Element ถัดไป
- Iterator::rewind - ม้วนกลับไป Element แรก
- Iterator::valid - ตรวจสอบตำแหน่งปัจจุบันถูกต้องไหม
Generator ทำงานเหมือน Forward-only Iterator มี Methods สำหรับจัดการ State รวมถึงส่งค่าเข้าและรับค่าจาก Generator
Generator as Iterator
ตัวอย่าง Generator Function Yield บรรทัดในไฟล์ สามารถ Traverse ด้วย Foreach เรียก Iterator Methods เช่น current() และ next() ได้ แต่ rewind() จะโยน Exception เพราะ Generator เป็น Forward-only:
<?php
function fileGenerator($name) {
$fileHandle = fopen($name, 'r');
while ($line = fgets($fileHandle)) {
yield $line;
}
fclose($fileHandle);
}
$name = "test.txt";
$file = fileGenerator($name);
foreach ($file as $line) {
echo $line;
}
$file->rewind(); // Error!
echo $file->current();
$file->next();
echo $file->current();
?>
ผลลัพธ์
PHP Fatal error: Uncaught Exception: Cannot rewind a generator that was already run
ความแตกต่างสำคัญ: Generator vs Iterator Implementation
| คุณสมบัติ | Generator | Iterator Implementation |
|---|---|---|
| Boilerplate Code | น้อยมาก (แค่ yield) | มาก (Implement 5 Methods) |
| State Management | Auto (PHP จัดการ) | Manual (Developer จัดการ) |
| Rewindable | ไม่ได้ (Forward-only) | ได้ (ถ้า Implement rewind) |
| Memory | Low (Lazy) | ขึ้นอยู่กับ Implementation |
| Send Values | ได้ (send()) | ไม่ได้โดยตรง |
| Return Value | ได้ (getReturn()) | ไม่ได้ |
Generator Methods เพิ่มเติม
send($value)- ส่งค่าเข้า Generator (รับผ่าน yield expression)throw($exception)- โยน Exception เข้า GeneratorgetReturn()- รับค่า Return ของ Generatorvalid(),current(),key(),next(),rewind()- Iterator Methods
ตัวอย่าง send()
<?php
function logger() {
while (true) {
$msg = yield;
echo "LOG: $msg\n";
}
}
$log = logger();
$log->send("First message");
$log->send("Second message");
$log->send("Third message");
?>
ผลลัพธ์
LOG: First message LOG: Second message LOG: Third message
สรุป
- Generator = Syntax Sugar สำหรับ Iterator แบบ Forward-only
- เหมาะกับ One-pass Iteration (ไฟล์, Stream, Large Dataset)
- ต้องการ Rewind/Multiple Passes → Implement Iterator Interface เอง
- Generator ให้ Advanced Features: send, throw, getReturn