PHP 生成器 - 垃圾收集

PHP Generators - Garbage Collection

简单的问题。

生成器何时或如何由 PHP 或您自己销毁它们的堆栈?

举个例子:

function doWork(): Generator
{
    // create some objects.
    $o1 = new stdClass();
    $o2 = new stdClass();

    // pause here and wait for data.
    $value = yield 1;

    // By referencing the above objects, they shouldn't destruct.
    $o1->property = $value;
    $o2->property = $value;

    yield $o1;
    yield $o2;

    // End of stack.
}

// Create the generator.
$generator = doWork();

$value = $generator->current(); // $value will equal 1.

if ($x) {
    $generator->send('Hello, World!'); // Continue execution of the generator.
    $o1 = $generator->current();
    $generator->next();
    $o2 = $generator->current();
    $generator->next(); // Complete the generator

    var_dump($o1);
    var_dump($o2);
} else {
    // Do nothing with the generator.
}

// Carry on with script ...

在此示例中,启动了一个生成器并创建了两个对象。此时已生成,并请求进一步的数据。

达到 IF 语句。

案例一

如果 $x 为真,值 "Hello, World!" 将被发送到生成器,并且对象将使用它们的新属性填充。

下次读取生成的数据时,将返回对象。

案例二

如果$x为false,生成器将不再使用。

问题

在情况 1 中,我希望堆栈像任何其他函数一样关闭,但在情况 2 中生成器会发生什么情况?它和所有剩余的对象引用是否会保留在内存中直到脚本结束?

或者是丢失对$generator的引用导致的,里面的所有引用都被清除了?

生成器销毁其执行上下文(也包括变量table)有两种情况:

  1. 如果生成器完成执行。这可能通过执行 return(包括函数末尾的隐式 return)或在生成器执行期间通过未捕获的异常发生。
  2. 如果放弃对生成器对象的所有引用。

所以,不,生成器在脚本结束之前不会生效。一旦 $generator 变量超出范围,它将被销毁,此时生成器将放弃其对变量值和其他执行状态的引用。

您可以通过在析构函数中创建 echo 的 class,然后将此 class 实例化为局部变量来轻松观察销毁顺序。