jced-artem / leak-safe-generator
生成器包装器,用于防止内存泄漏
1.0.0
2016-12-13 15:59 UTC
Requires
- php: >=5.5.0
Requires (Dev)
- php: >=5.5.0
This package is not auto-updated.
Last update: 2024-09-28 19:31:21 UTC
README
安装
composer require jced-artem/leak-safe-generator
如果您在使用带有处理器的生成器时想防止内存泄漏,同时又不想使用 try..finally
结构,这个类可以帮到您。
示例
function parsePages() {
$ch = curl_init();
// ... some options
while ($condition) {
yield curl_exec($ch);
}
curl_close($ch);
}
foreach (parsePages() as $page) {
if ($someCondition) {
break;
}
// ...
}
问题
如果您在获取所有产生值之前就中断循环,那么您将无法关闭处理器 $ch
,这可能导致内存泄漏。
解决方案
function parsePages() {
$ch = curl_init();
// ... some options
try {
$finished = false;
while ($condition) {
yield curl_exec($ch);
}
$finished = true;
} finally {
// close anyway
curl_close($ch);
if ($finished) {
// do something if reached last element
} else {
// do something on break
}
}
}
新问题
如果创建多个生成器,这段代码将不可用
新解决方案
$lsg = new LeakSafeGenerator();
$lsg
->init(function() {
$this->ch = curl_init();
// ... some options
while ($condition) {
yield curl_exec($this->ch);
}
})
->onInterrupt(function() {
// do something on break
})
->onComplete(function() {
// do something if reached last element
})
->onFinish(function() {
curl_close($this->ch);
})
;
foreach ($lsg->getGenerator() as $page) {
if ($someCondition) {
break;
}
// ...
}
或简短版本
$lsg = new LeakSafeGenerator(
function() {
$this->ch = curl_init();
// ... some options
while ($condition) {
yield curl_exec($this->ch);
}
},
function() {
curl_close($this->ch);
}
);
您不需要为每个生成器创建额外的函数和方法,也不需要为每个生成器编写 try..finally
结构。