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.