我有一些非常大的xml文件用于计划导入。我使用 cron 来解析它们。问题是处理需要太多时间,并且总是超过php"max_execution_time"。由于我使用 XMLReader,这允许"逐行"读取 xml,这是我看到的唯一解决方案:跟踪当前的工作"节点",记住它并在下一次 cron 运行时设置节点偏移量。
现在我有
$xml = new XMLReader;
$xml->open($file);
$pointer = 0;
while($xml->read()) {
if ($xml->nodeType == XMLReader::ELEMENT && $xml->localName == 'Product') {
$chunk = array();
$chunk['ProductID'] = $xml->getAttribute('ProductID');
$chunk['ProductName'] = $xml->getAttribute('ProductName');
process_import($chunk); // Process received date
save_current_node_in_BD($pointer++); // insert current position in BD
}
}
$xml->close();
}
使用 $pointer++ 对已处理的节点进行计数是个好主意吗?如何为下一次 cron 运行设置偏移量?
首先,当你从cron执行php时,你通常使用默认max_execution_time为0(禁用)的cli版本。如果您无法更改,请继续阅读。
如果您的 XML 可以在时间内解析(仅解析,不处理),则可以有两个 crons:
- 第一个 cron 将解析 XML 并将新任务转储到一堆上。
- 第二个 cron 将从堆中获取工作,处理它,然后将其从堆中删除。
桩可以通过几种方式实现,其中包括:
- 数据库表 工作项
- 目录(每个工作项是一个文件)
编辑
如果无法禁用执行时间限制,则可以保留一个包含文件名和位置的小文件。在每次迭代中,您可以打开此文件以确定是否仍有工作要做。为了确保它在时间用完时保存该文件,您需要注册一个关闭函数。