PHP:如何在生成器函数之后进行清理
经过一些研究,我被说服为许多任务使用生成器(更一般地说,迭代器),这些任务通常会将结果缓冲到一个数组中,因为内存使用是O(1)而不是O(n) 因此,我计划使用生成器处理通过mysqli查询的数据库结果。关于这种方法,我有两个问题无法找到答案,我希望社区能给我一些创造性的解决方案:PHP:如何在生成器函数之后进行清理,php,mysql,mysqli,Php,Mysql,Mysqli,经过一些研究,我被说服为许多任务使用生成器(更一般地说,迭代器),这些任务通常会将结果缓冲到一个数组中,因为内存使用是O(1)而不是O(n) 因此,我计划使用生成器处理通过mysqli查询的数据库结果。关于这种方法,我有两个问题无法找到答案,我希望社区能给我一些创造性的解决方案: 如果使用代码选择不完全迭代结果,是否有办法释放生成器打开的资源?使用迭代器类,可以在_destruct方法中执行此操作。但是,根据我的测试,如果生成器不能自然结束,它将不会按照迭代序列执行代码。我正在寻找解决方法,以避
function query($mysqli, $sql){
$result = $mysqli->query($sql);
foreach($result as $row){
yield $row;
}
$result->free(); //Never reached if break, exception, take first n rows, etc.
}
tl;dr is我只是好奇如何释放生成器使用的资源,以及随后用于数据库访问的生成器是否真的保存了任何内容,或者结果是否被缓冲
更新
这里的()看起来像默认情况下的PHP缓冲区查询,可能会破坏生成器的功能。尽管可以这样说,只缓冲一个数组比创建一个缓冲数组的副本然后拥有两个缓冲集要好
我正在寻找在这件事上有经验的人参与进来。谢谢你的想法 我可能会晚一点参加聚会,但是如果您正在使用生成器,并且需要在完成时进行清理(比如在完成所有循环之前中断父循环),您可以在finally块中使用try/catch/finally进行清理:
function query($mysqli, $sql){
$result = $mysqli->query($sql);
foreach($result as $i => $row) {
if ($i + 1 === $result->num_rows) {
$result->free();
}
yield $row;
}
}
function query($mysqli, $sql) {
$result = $mysqli->query($sql);
try {
if ($result) {
foreach($result as $row) {
yield $row;
}
}
} catch (Exception $e) {
throw $e; // send this up the stack (or you could handle here)
} finally {
$result->free(); // clean up when the loop is finished.
}
}
下面介绍如何检测循环中断,以及如何在中断后处理或清理
function generator()
{
$complete = false;
try {
while (($result = some_function())) {
yield $result;
}
$complete = true;
} finally {
if (!$complete) {
// cleanup when loop breaks
} else {
// cleanup when loop completes
}
}
// Do something only after loop completes
}
不幸的是,与上面的初始解决方案相比,这并没有什么好处,因为在这两种情况下都必须完全迭代结果集。添加
finally
块使得catch
是可选的。如果不处理异常,则不应捕获它。