PHP 中的“ClosedGeneratorException”是什么?
In PHP, what is the `ClosedGeneratorException`?
在 PHP 7.0 和 7.1 中查看 get_declared_classes()
的输出时,我注意到 ClosedGeneratorException
.
手册中没有 much mention of it and it does not seem to be listed on either the Predefined Exceptions or SPL exceptions 个条目。
甚至源代码也not hold much information about it。
那么,什么是ClosedGeneratorException
?
(有什么用?什么时候出现?应该什么时候用?)
根据评论中的回复,我能够回答我自己的问题
code in the PHP core that throws this exception 状态:
/* php-src/Zend/zend_generators.c */
zend_throw_exception(
zend_ce_ClosedGeneratorException,
"Generator yielded from aborted, no return value available",
0
);
有an article on airbrake.io进入ClosedGeneratorException
的细节:
A ClosedGeneratorException
occurs when attempting to perform a traversal on a generator that has already been closed or terminated.
换句话说,当生成器有运行个值时,请求一个新值会触发这个异常。(1)
基于 this test from the PHP core 我构建了两个场景,其中 ClosedGeneratorException
被抛出(并被捕获)。
通过从内部生成器中抛出异常(使用 yield from
syntax)可以很容易地模拟这种行为。例外是 only 从 Generator 内部抛出。 (尽管它 可以 在生成器外捕获)。
下面附有两个场景。这两个例子都可以在ideone.com(2)(3)
上看到运行ning
两个例子的输出如下:
在生成器中捕获 ClosedGeneratorException
(2)
Generator: 0
1
Generator: 1
Caught ClosedGeneratorException
在发电机外捕捉 ClosedGeneratorException
(3)
Generator: 0
Caught Generic Exception
Generator: 1
Caught ClosedGeneratorException
脚注
- 文章提供了一个触发异常的示例,但该示例似乎不起作用(因为抛出了常规异常)。
- 在生成器中捕获
ClosedGeneratorException
:https://ideone.com/FxTLe9
- 在发电机外捕捉
ClosedGeneratorException
:https://ideone.com/ipEgKx
代码示例
在发电机中捕获 ClosedGeneratorException
:
<?php
class CustomException extends Exception {}
function from() {
yield 1;
throw new CustomException();
}
function gen($gen) {
try {
yield from $gen;
} catch (\ClosedGeneratorException $e) {
yield "Caught ClosedGeneratorException";
} catch (\Exception $e) {
yield "Caught Generic Exception";
}
}
$gen = from();
$gens[] = gen($gen);
$gens[] = gen($gen);
foreach ($gens as $g) {
$g->current(); // init.
}
foreach ($gens as $i => $g) {
print "Generator: $i\n";
print $g->current()."\n";
$g->next();
}
在发电机外捕获 ClosedGeneratorException
:
<?php
class CustomException extends Exception {}
function from() {
yield 1;
throw new CustomException();
}
function gen($gen) {
yield from $gen;
}
$gen = from();
$gens[] = gen($gen);
$gens[] = gen($gen);
foreach ($gens as $g) {
$g->current(); // init.
}
foreach ($gens as $i => $g) {
print "Generator: $i\n";
try {
$g->current();
$g->next();
} catch (\ClosedGeneratorException $e) {
print "Caught ClosedGeneratorException\n";
} catch (\Exception $e) {
print "Caught Generic Exception\n";
}
}
在 PHP 7.0 和 7.1 中查看 get_declared_classes()
的输出时,我注意到 ClosedGeneratorException
.
手册中没有 much mention of it and it does not seem to be listed on either the Predefined Exceptions or SPL exceptions 个条目。
甚至源代码也not hold much information about it。
那么,什么是ClosedGeneratorException
?
(有什么用?什么时候出现?应该什么时候用?)
根据评论中的回复,我能够回答我自己的问题
code in the PHP core that throws this exception 状态:
/* php-src/Zend/zend_generators.c */
zend_throw_exception(
zend_ce_ClosedGeneratorException,
"Generator yielded from aborted, no return value available",
0
);
有an article on airbrake.io进入ClosedGeneratorException
的细节:
A
ClosedGeneratorException
occurs when attempting to perform a traversal on a generator that has already been closed or terminated.
换句话说,当生成器有运行个值时,请求一个新值会触发这个异常。(1)
基于 this test from the PHP core 我构建了两个场景,其中 ClosedGeneratorException
被抛出(并被捕获)。
通过从内部生成器中抛出异常(使用 yield from
syntax)可以很容易地模拟这种行为。例外是 only 从 Generator 内部抛出。 (尽管它 可以 在生成器外捕获)。
下面附有两个场景。这两个例子都可以在ideone.com(2)(3)
上看到运行ning两个例子的输出如下:
在生成器中捕获
ClosedGeneratorException
(2)Generator: 0 1 Generator: 1 Caught ClosedGeneratorException
在发电机外捕捉
ClosedGeneratorException
(3)Generator: 0 Caught Generic Exception Generator: 1 Caught ClosedGeneratorException
脚注
- 文章提供了一个触发异常的示例,但该示例似乎不起作用(因为抛出了常规异常)。
- 在生成器中捕获
ClosedGeneratorException
:https://ideone.com/FxTLe9 - 在发电机外捕捉
ClosedGeneratorException
:https://ideone.com/ipEgKx
代码示例
在发电机中捕获 ClosedGeneratorException
:
<?php
class CustomException extends Exception {}
function from() {
yield 1;
throw new CustomException();
}
function gen($gen) {
try {
yield from $gen;
} catch (\ClosedGeneratorException $e) {
yield "Caught ClosedGeneratorException";
} catch (\Exception $e) {
yield "Caught Generic Exception";
}
}
$gen = from();
$gens[] = gen($gen);
$gens[] = gen($gen);
foreach ($gens as $g) {
$g->current(); // init.
}
foreach ($gens as $i => $g) {
print "Generator: $i\n";
print $g->current()."\n";
$g->next();
}
在发电机外捕获 ClosedGeneratorException
:
<?php
class CustomException extends Exception {}
function from() {
yield 1;
throw new CustomException();
}
function gen($gen) {
yield from $gen;
}
$gen = from();
$gens[] = gen($gen);
$gens[] = gen($gen);
foreach ($gens as $g) {
$g->current(); // init.
}
foreach ($gens as $i => $g) {
print "Generator: $i\n";
try {
$g->current();
$g->next();
} catch (\ClosedGeneratorException $e) {
print "Caught ClosedGeneratorException\n";
} catch (\Exception $e) {
print "Caught Generic Exception\n";
}
}