PHP yield from Keyword - Delegate Generator
The yield from keyword in PHP revolutionizes the way developers handle generators by allowing seamless delegation of generator execution to another generator or any traversable. This not only simplifies the code when working with multiple generators but also enhances readability and maintainability.
Introduction
Generators in PHP allow you to write iterators in a simple way without the need to build a class implementing Iterator. The yield from keyword, introduced in PHP 7, extends generator capabilities by letting one generator delegate iteration to another generator or traversable. This enhances composability and efficiency when dealing with complex iteration scenarios.
Prerequisites
- Basic knowledge of PHP syntax
- Understanding of generators and
yieldkeyword - PHP version 7.0 or higher (for
yield fromsupport)
Setup Steps
- Ensure your PHP environment is version 7.0 or higher.
- Use any modern editor or IDE (VSCode, PHPStorm, Sublime Text).
- Create PHP files with generators to experiment.
- Run your code in CLI or via a web server to observe output.
Understanding yield from with Examples
Basic Generator Example Without yield from
function letters() {
yield 'a';
yield 'b';
yield 'c';
}
function numbers() {
yield 1;
yield 2;
yield 3;
}
function combined() {
foreach (letters() as $letter) {
yield $letter;
}
foreach (numbers() as $number) {
yield $number;
}
}
foreach (combined() as $value) {
echo $value . ' ';
}
// Output: a b c 1 2 3
The above example uses foreach to manually delegate the iteration from one generator to another.
Equivalent Example Using yield from
function letters() {
yield 'a';
yield 'b';
yield 'c';
}
function numbers() {
yield 1;
yield 2;
yield 3;
}
function combined() {
yield from letters();
yield from numbers();
}
foreach (combined() as $value) {
echo $value . ' ';
}
// Output: a b c 1 2 3
Using yield from delegates the iteration internally and reduces boilerplate, making code cleaner.
Delegating to Traversable Objects
function iterArray(array $items) {
yield from $items;
}
foreach (iterArray(['x', 'y', 'z']) as $char) {
echo $char . ' ';
}
// Output: x y z
yield from can delegate to arrays or any object implementing Traversable interface, not just generators.
Using yield from with Return Values
Generators can return values that can be retrieved by the delegating generator using yield from. This is very useful for coroutine-like behavior.
function generatorA() {
yield 1;
yield 2;
return 'Done A';
}
function generatorB() {
$result = yield from generatorA();
echo "Returned from generatorA: $result\n";
yield 3;
yield 4;
}
foreach (generatorB() as $val) {
echo $val . ' ';
}
// Output:
// Returned from generatorA: Done A
// 1 2 3 4
Best Practices
- Use
yield fromto simplify delegating generator loops instead of nestedforeach. - Combine multiple small generators with meaningful purposes for better modularity.
- Ensure delegated generators return values if you expect to handle them in the main generator.
- Prefer
yield fromover manual iteration when dealing with traversable datasets. - Write unit tests for generators to verify correct sequence and return values.
Common Mistakes
- Using
yield fromwith non-traversable variables (causes a fatal error). - Expecting
yield fromto flatten deep nested arrays without generators. - Not capturing the return value of delegated generators when needed.
- Using
yield fromin PHP versions older than 7.0. - Confusing
yield fromwith justyield, leading to incomplete delegation.
Interview Questions
Junior Level Questions
- Q: What is the purpose of the
yield fromkeyword in PHP?
A: It delegates the execution of a generator to another generator or traversable, simplifying iteration. - Q: Which PHP version introduced
yield from?
A: PHP 7.0. - Q: Can
yield fromdelegate to arrays?
A: Yes, arrays are traversable and can be delegated to. - Q: What does the
yieldkeyword do in PHP?
A: It creates a generator by yielding values one at a time. - Q: Why is
yield frompreferred over manual looping viaforeachinside generators?
A: It simplifies code and improves readability by directly delegating iteration.
Mid Level Questions
- Q: How can you retrieve the return value from a delegated generator in
yield from?
A: The return value of the delegated generator is assigned to the variable on the left side of= yield from. - Q: What types of data can
yield fromdelegate to besides generators?
A: Any traversable object like arrays or objects implementingTraversable. - Q: What will happen if you use
yield fromwith a non-traversable variable?
A: It will cause a fatal error since the variable must be traversable. - Q: Explain a practical use case for
yield from.
A: Combining multiple smaller generators into a single iterator or handling complex iterative workflows like coroutines. - Q: Can
yield frombe nested? If yes, how?
A: Yes, generators can delegate to other generators that themselves useyield from, enabling multiple levels of delegation.
Senior Level Questions
- Q: How does
yield fromimprove performance compared to nested foreach iteration?
A: It reduces overhead by delegating control internally at the engine level, avoiding multiple context switches between generators and manual loops. - Q: Describe how
yield frompropagates exceptions from delegated generators.
A: Exceptions thrown inside the delegated generator bubble up throughyield fromto the caller, enabling centralized exception handling. - Q: What happens to the keys yielded by a delegated generator when using
yield from?
A: Keys are preserved and yielded directly by the delegating generator, maintaining the original keys. - Q: Can
yield frombe used to delegate to asynchronous generator functions or coroutines?
A: Yes, it can delegate yield values from asynchronous generators to combine multiple asynchronous streams. - Q: How can you access the value sent into a generator when using
yield fromdelegation?
A: Sent values propagate throughyield fromto the delegated generatorโsyieldstatement, enabling communication between caller and nested generator.
Frequently Asked Questions (FAQ)
Does yield from only work with generators?
No, yield from works with any traversable, including arrays and objects implementing the Traversable interface.
What versions of PHP support yield from?
PHP 7.0 and later versions support yield from.
Can I use yield from to combine multiple datasets?
Yes, itโs an efficient way to combine multiple generator or traversable datasets into a single iterator.
How do I get the return value from a delegated generator?
Assign the yield from expression to a variable. The delegated generatorโs return value will be stored in that variable.
Is it possible to nest yield from calls?
Yes, multiple nested generators can delegate to each other using yield from, allowing flexible data flow compositions.
Conclusion
The yield from keyword is a powerful feature that improves the way PHP developers handle generators. By delegating iteration to other generators or traversable objects seamlessly, it enhances code clarity and performance. Understanding how to use yield from properly enables you to create modular, maintainable, and efficient generator-based workflowsโa critical skill for modern PHP development.