php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77587 Inconsistent behaviour when returning generators
Submitted: 2019-02-08 12:03 UTC Modified: 2019-02-08 12:07 UTC
From: adamnicholson10 at gmail dot com Assigned:
Status: Not a bug Package: *General Issues
PHP Version: Irrelevant OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: adamnicholson10 at gmail dot com
New email:
PHP Version: OS:

 

 [2019-02-08 12:03 UTC] adamnicholson10 at gmail dot com
Description:
------------
There appears to be inconsistent behaviour when returning generators.

Given the function `foo()` returns a generator, when you consume that generator in a new function which also returns a generator, you would expect `return foo()` to have the same behaviour as looping over the values of `foo()` and performing a `yield` on each value; however this doesn't appear to be the case if the function you are consuming `foo()` contains other yield statements.

It looks like PHP is getting confused by having both `yield` statements, and `return $generator` statements, in the same function body.

This appears to affect all PHP versions tested which support generators

POC (code below): https://3v4l.org/e86mK

Test script:
---------------
<?php

function generator() {
    foreach ([1, 2, 3, 4, 5] as $i) {
        yield $i;
    }
}

function A(): \Generator {
    return generator();
}

function B(): \Generator {
    if (false) {
        yield 7;
        return;
    }
    return generator();
}

function C(): \Generator {
    if (false) {
        yield 7;
        return;
    }
    foreach (generator() as $i) {
        yield $i;
    }
}

echo "-A\n";
foreach (A() as $i) {
    echo "{$i}\n";
}

echo "-B\n";
foreach (B() as $i) {
    echo "{$i}\n";
}

echo "-C\n";
foreach (C() as $i) {
    echo "{$i}\n";
}

echo "Done\n";


Expected result:
----------------
-A
1
2
3
4
5
-B
1
2
3
4
5
-C
1
2
3
4
5
Done

Actual result:
--------------
-A
1
2
3
4
5
-B
-C
1
2
3
4
5
Done

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-02-08 12:07 UTC] nikic@php.net
-Status: Open +Status: Not a bug
 [2019-02-08 12:07 UTC] nikic@php.net
return foo() is just that: You are returning a generator object.

What you are looking for is "yield from foo()". See also http://php.net/manual/en/language.generators.syntax.php#control-structures.yield.from
 
PHP Copyright © 2001-2026 The PHP Group
All rights reserved.
Last updated: Thu Oct 08 02:00:01 2026 UTC