0

我一直在使用 simplexml_load_file 来解析具有 15,000 条记录的 xml 文件,它工作正常,但是当我尝试处理许多文件时,每个文件都是 15,000,它给了我这个 errorPHP

Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 64 bytes)

不知道该怎么做,以下是我正在做的示例,

$xml = simplexml_load_file($file)
       or die("Error: Cannot create object");

foreach($xml->children() as $events){
                foreach($events->load as $load){
                        $record = $load->loadrecord['record']."    ";
                        if ($load->loadrecord['record'] == "test"){
                                foreach($events->receiveds as $received){
                                $release = $received->received['release'];
                                }
                                foreach($events->sender as $sender){
                                $test1 = $sender['test1'];
                                $test2 = $sender['test2'];
                                $test3 = $sender['test3'];
                                $test4 = $sender['test4'];
                                }
                                foreach($events->screens as $filter){
                                $record = $filter->filter['record'];
                                }
                        }
}

解析完成后是否需要释放一些东西,请注意文件很多时会出现问题,我尝试了两个文件,没有问题

4

4 回答 4

2

不要对大文件使用 simplexml。使用 XML DOM 对象。

您可以使用一些高级工具,如 SAX 或 XMLReader 或其他第三方来解析数据。

于 2012-11-02T22:38:23.727 回答
1

终于找到问题了,每次迭代后都需要取消设置,比如这里需要取消设置$xml

$xml = simplexml_load_file(file_name )
foreach($xml->children() as $logs){
do_stuff
unset($xml);
}

我之前的情况是这样的

$xml = simplexml_load_file(file_name )
foreach($xml->children() as $logs){
do_stuff
}
unset($xml);

没有你的指导不会真的找到它

于 2012-11-03T03:33:28.177 回答
0

不幸的是,SimpleXML 类将整个 XML 文件加载到内存中。如果你给它一个大文件,这显然会给你带来问题。

相反,您需要使用 XMLReader 类。此类一次读取一个 XML 元素,并在读取后将其丢弃。这意味着您在任何时候都有最少的数据在内存中。

使用此类的一种便捷方法是将其包装在 Iterator 类中。这意味着您可以使用foreach()循环遍历元素,就好像它们是一次性加载的一样。

这是XMLReader 的 Iterator 类的一个很好的示例的链接。当我遇到这个问题时,我发现这门课很有帮助。我不得不进行一些小的调整以满足我的需要,但它在第一次时几乎奏效了。我希望它也适合你。

于 2012-11-02T22:54:20.197 回答
0

您可以考虑使用 cron 作业一个接一个地处理这些文件,然后将它们的输出存储在某处并在完成时检索输出。

这当然取决于您不需要立即获得结果。如果你这样做了,你可以开始这个过程并使用 AJAX 请求来检查它何时完成并获取最终输出。

显然,需求和要求可能意味着这是不可行的。提高内存限制是一种选择,但如果您在共享托管平台上,通常不会。这也只是意味着您绕过问题,而不是解决问题(即如果记录数再次增加,问题将再次出现)

编辑:误读问题,修改答案以适应。

于 2012-11-02T22:04:26.907 回答