【问题标题】:Recursive directory iterator with offset具有偏移量的递归目录迭代器
【发布时间】:2014-12-18 13:21:13
【问题描述】:

是否可以从某个点开始循环?

$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;
}

但是我如何在下一个请求中从我的断点恢复?

【问题讨论】:

  • 1.恢复已处理项目的数量;如果未设置,则将其初始化为零; 2.进入循环,跳过处理的项目数; 3.处理一项; 4.数一数; 5. 打破循环; 6. 将值传递给下一个请求(使用会话或查询字符串)。冲洗并重复。

标签: php file-io recursion


【解决方案1】:

a) 从 foreach 中提取时间计算。您有一个开始时间,并且您希望运行时间为 5 秒,因此您可以预先计算结束时间(开始时间 + 5 秒)。在 foreach 中,只需比较 time 是否大于或等于 endtime,然后 break。

b) 问:是否可以从某个点开始循环?如何在下一个请求中从断点恢复?

我想到了两种方法。

您可以存储最后一个处理点和迭代器并在最后一个点 + 1 处继续。 您将保存迭代的最后一个位置并在下一个请求时快进到它,方法是调用 iterator->next() 直到您到达下一个要处理的项目,即 $lastPosition+1。 我们必须存储迭代器和 lastPosition 并在下一个请求中获取它们,直到 lastPosition 等于迭代器中的元素总数。

或者,您可以在第一次运行时将迭代器转换为数组:$array = iterator_to_array($iterator);,然后使用 reduce 数组方法。 (也许其他人知道如何减少迭代器对象。) 使用这种方法,您将只存储数据,这会逐个请求减少请求,直到 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...

总而言之,这是批处理,可能由工作/作业队列更有效地完成,例如:

【讨论】:

  • 谢谢,我会试试 Gearman。我曾考虑将整个数组存储在某个地方,但在某些情况下它可以达到 20 万个元素,而且我很确定这会占用 PHP 中的大量资源
猜你喜欢
  • 2012-11-06
  • 2014-07-30
  • 2013-12-01
  • 1970-01-01
  • 2020-10-09
  • 2013-01-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多