nic*_*ass 7 php recursion file-io
是否有可能从某一点开始循环?
$iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path, $flags));
$startTime = microtime(true);
foreach($iterator as $pathName => $file){
// file processing here
// after 5 seconds stop and continue in the next request
$elapsedSecs = (microtime(true) - $startTime);
if($elapsedSecs > 5)
break;
}
Run Code Online (Sandbox Code Playgroud)
但是,如何在下一个请求中从断点恢复?
a) 将时间计算从 foreach 中取出。您有一个开始时间,并且希望运行时间为 5 秒,因此您可以提前计算结束时间(开始时间 + 5 秒)。在 foreach 中,只需比较时间是否大于或等于结束时间,然后中断。
b) 问:是否可以从某个点开始循环?如何在下一个请求中从断点恢复?
我想到了两种方法。
您可以存储最后一个处理点和迭代器,并在最后一个点 + 1 处恢复。您可以保存迭代的最后一个位置,并在下一个请求时快进到它,通过调用 iterator->next() 直到到达下一个要处理的项目,即 $lastPosition+1。我们必须存储迭代器和lastPosition,并在下一个请求时选取两者,直到lastPosition等于迭代器中的元素总数。
或者,您可以在第一次运行时将迭代器转换为数组:$array = iterator_to_array($iterator);然后使用归约数组方法。(也许其他人知道如何减少迭代器对象。)使用这种方法,您将只存储数据,这会逐个减少请求,直到 0。
该代码未经测试。这只是一个快速的草稿。
$starttime = time();
$endtime = $starttime + (5 * 60); // 5sec
$totalElements = count($array);
for($i = 0; $i <= $totalElements; $i++)
{
if(time() >= $endtime) {
break;
}
doStuffWith($array[$i]);
}
echo 'Processed ' . $i . ' elements in 5 seconds';
// exit condition is "totalElements to process = 0"
// greater 1 means there is more work to do
if( ($totalElements - $i) >= 1) {
// chop off all the processed items from the inital array
// and build the array for the next processing request
$reduced_array = array_slice(array, $i);
// save the reduced array to cache, session, disk
store($reduced_array);
} else {
echo 'Done.';
}
// on the next request, load the array and resume the steps above...
Run Code Online (Sandbox Code Playgroud)
总而言之,这是批处理,可以由工作人员/作业队列更有效地完成,例如: