Generators (yield)
Need to loop over a million rows, or the lines of a huge file, without exhausting memory? Generators produce values lazily — one at a time, on demand — using the yield keyword. They look like normal functions but sip memory instead of gulping it.
Learn Generators (yield) in our free PHP course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick recall.
Part of the free Php course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
1️⃣ Your First Generator
Any function containing yield becomes a generator . Calling it doesn't run the body — it returns a Generator object. Iterating with foreach runs the body until the first yield , hands that value back, and pauses . The next loop iteration resumes right where it left off. Watch the interleaved output below — it proves each value is generated only when asked for.
2️⃣ Why Generators Save Memory
This is the headline benefit. Building an array of a million integers would allocate space for all million at once. A generator holds just one value at a time, so the loop below sums a million numbers while memory usage stays essentially flat. Same result, a fraction of the footprint.
3️⃣ Yielding Keys and Values
Just like an array, a generator can produce key => value pairs with yield $key => $value . A bare yield; produces null with auto-incrementing integer keys. Helpers like iterator_count() work on any generator.
4️⃣ Streaming Real Data
The everyday win is streaming. Reading a multi-gigabyte log file line by line through a generator means you process one line at a time and never load the whole file. Here we simulate it with a small array, but the shape — yield each item, process it in the loop — is exactly how you'd wrap fgets() over a real file handle.
Now you try — fill in each ___ using the 👉 hint, then run it and check against the Output panel.
These lines define a generator and consume it — but they're scrambled. Put them in the order that prints ab .
Declare the generator: open the function ( C ), yield 'a' then 'b' ( B , D ), close it ( E ). Then iterate ( A ), which resumes the body twice and prints ab .
start — only that. Calling g() returns a generator without running the body; 'A' wouldn't print until you start iterating.
60 — the loop pulls 10, 20, then 30 from the generator and adds them.
Nothing (empty) — a generator can be consumed only once . After the first loop exhausts it, the second loop has nothing left to yield.
📋 Quick Reference — Generators
No code is filled in this time — just a brief and an outline. Write it yourself, run it on onecompiler.com/php or your own machine, then check your result against the expected output in the comments.
Practice quiz
What keyword turns an ordinary function into a generator?
- return
- generate
- yield
- async
Answer: yield. Any function containing yield becomes a generator that produces a series of values one at a time.
What happens when you CALL a generator function (before iterating it)?
- It returns a Generator object without running the body
- Its body runs fully and returns an array
- It throws until you add a loop
- It runs up to the first yield only
Answer: It returns a Generator object without running the body. Calling a generator function does not run its body — it returns a Generator object. The body runs only when you iterate it.
For function g() { echo 'A'; yield 1; } $gen = g(); echo 'start'; what prints?
- Astart
- startA
- A1start
- start
Answer: start. Only 'start' prints. Calling g() returns a generator without running the body, so 'A' would not print until you start iterating.
What does yield do to the function's execution?
- Ends the function permanently
- Hands a value to the loop and pauses, preserving local state
- Restarts the function from the top
- Skips to the next function
Answer: Hands a value to the loop and pauses, preserving local state. yield hands the value back and freezes the function exactly there, preserving locals and the instruction pointer; it resumes after the yield on the next iteration.
Why are generators so memory-efficient for large sequences?
- Only one value lives in memory at a time
- They compress the array
- They cache to disk
- They use less CPU
Answer: Only one value lives in memory at a time. A generator holds just one value at a time instead of materialising the whole set, so memory stays nearly flat however large the range.
How many times can a generator be iterated?
- As many times as you want
- Twice
- Exactly once — it cannot be rewound
- Until you call reset()
Answer: Exactly once — it cannot be rewound. A generator can be iterated only once and cannot be rewound. Call the function again for a fresh one, or capture values with iterator_to_array().
Which helper converts a generator into a real array?
- array_from()
- iterator_to_array()
- generator_array()
- to_array()
Answer: iterator_to_array(). iterator_to_array() materialises a generator's values into an array, trading memory for re-iterability.
How do you produce a key => value pair from a generator?
Just like an array, a generator can produce pairs with yield $key => $value.
For function nums() { yield 10; yield 20; yield 30; } summed in a foreach, what is the total?
- 30
- 60
- 10
- 0
Answer: 60. The loop pulls 10, 20, then 30 from the generator and adds them: 60.
What does yield from do?
- Imports a class
- Returns early
- Delegates to another generator or iterable, flattening it
- Reverses the sequence
Answer: Delegates to another generator or iterable, flattening it. yield from delegates to another generator or iterable, cleanly flattening nested sources into the current generator.