W3docs

yield

The yield keyword is used in PHP to create a generator function. A generator is a special kind of function that can be paused and resumed during execution,

Introduction

The yield keyword turns an ordinary PHP function into a generator — a function that produces a sequence of values one at a time, pausing after each value and resuming where it left off when the next value is requested. This page covers how yield works, how to yield keys, how to send values back into a generator, the yield from delegation syntax, and when generators save memory compared with building a full array.

A function becomes a generator the moment it contains at least one yield. Calling it does not run the body — it returns a Generator object. The body runs only as you iterate, advancing to the next yield each step. Because a generator implements the Iterator interface, you usually consume it with a foreach loop.

A first generator

Each yield hands one value to the caller and freezes the function until the next value is asked for.

php— editable, runs on the server

myGenerator() returns a generator object instead of running immediately. The foreach loop pulls values out of it: on each pass the function runs up to the next yield, emits that value, and pauses. The output is:

Hello World !

Unlike a function that builds and returns an array, all three strings are never held in memory at the same time — each is produced on demand. Compare this with how a normal function uses return to send back a single value and exit.

Yielding keys

A generator can yield key/value pairs with the yield $key => $value syntax, exactly like an associative array. The keys are available inside foreach:

<?php

function settings()
{
  yield "host" => "localhost";
  yield "port" => 5432;
  yield "user" => "admin";
}

foreach (settings() as $key => $value) {
  echo "$key = $value\n";
}

Output:

host = localhost
port = 5432
user = admin

If you don't supply keys, PHP auto-numbers yielded values starting at 0, just like an indexed array.

Generators are lazy: a memory-friendly range

The real benefit of yield is that values are computed only when needed. A generator that produces a million numbers uses constant memory, while an array of a million numbers allocates all of them up front.

<?php

function gen_range($start, $end)
{
  for ($i = $start; $i <= $end; $i++) {
    yield $i;
  }
}

$sum = 0;
foreach (gen_range(1, 1000000) as $n) {
  $sum += $n;
}

echo $sum;

Output:

500000500000

The loop never builds a [1, 2, …, 1000000] array; only one integer exists at a time. This is the pattern to reach for when reading huge files line by line or streaming database rows.

Returning a value from a generator

A generator may also use return to expose a final value (PHP 7+). The return value is not part of the iteration — you read it afterwards with getReturn():

<?php

function counter()
{
  yield 1;
  yield 2;
  return "done";
}

$gen = counter();
foreach ($gen as $value) {
  echo $value . " ";
}
echo $gen->getReturn();

Output:

1 2 done

Calling getReturn() before the generator has finished iterating throws an exception, so always exhaust it first.

Sending values in with send()

Generators are two-way: a yield expression can also receive a value sent from the caller via send(). This is the basis of coroutines.

<?php

function echoTimes()
{
  while (true) {
    $received = yield;
    echo "Got: $received\n";
  }
}

$gen = echoTimes();
$gen->current();      // prime the generator (run up to the first yield)
$gen->send("a");
$gen->send("b");

Output:

Got: a
Got: b

send($value) resumes the generator, making the paused yield expression evaluate to $value, then runs to the next yield.

Delegating with yield from

yield from (PHP 7+) yields every value from another generator, array, or Traversable, flattening it into the current one without a manual loop:

<?php

function inner()
{
  yield 2;
  yield 3;
}

function outer()
{
  yield 1;
  yield from inner();
  yield from [4, 5];
}

foreach (outer() as $value) {
  echo $value . " ";
}

Output:

1 2 3 4 5 

When to use a generator

  • Large or unbounded sequences — reading a multi-gigabyte file or an infinite stream where holding everything in an array is impossible.
  • Expensive values you may not need — if the consumer might stop early (break), a generator avoids computing the rest.
  • Cleaner iteration code — replacing a custom Iterator class with a single function.

Avoid generators when you need random access ($arr[42]), to count() results cheaply, or to iterate the same data multiple times — a generator can only be traversed once. For those cases, build a normal array, possibly with PHP functions like array_map.

Practice

Practice
What is the function of the 'yield' keyword in PHP?
What is the function of the 'yield' keyword in PHP?
Was this page helpful?