- gc_collect_cycles: documentation ( source)
- round: documentation ( source)
- memory_get_usage: documentation ( source)
- iterator_to_array: documentation ( source)
<?php
class IteratorWithFilter
{
public $generator;
public function __construct(array $data)
{
$this->generator = new \ArrayIterator($data);
}
public function filter()
{
$weakRef = WeakReference::create($this);
$this->generator = new CallbackFilterIterator($this->generator, static function(array $row) use ($weakRef) {
$filterObj = $weakRef->get();
return $filterObj->matchRow($row);
});
$this->generator->filterObj = $this; // this assigment will link the objects exactly the same as if
// bound function is passed directly, thus the WeakReference
// will always be valid/nonGCed
return $this;
}
public function matchRow(array $row) {
return $row[0] === 'b';
}
}
function createIterator() {
$iter = new IteratorWithFilter([['a'], ['b']]);
return $iter->filter();
}
for ($i = 0; $i < 10 * 1000; $i++) {
$generator = createIterator()->generator;
iterator_to_array($generator); // must success and always return ['b']
if (($i % 10) === 0) {
gc_collect_cycles();
}
if (($i % 1000) === 0) {
echo round(memory_get_usage() / (1024 * 1024), 3) . " MiB\n";
}
}