php中的simplexml_load_file

时间:2012-11-02 21:10:19

标签: php xml simplexml

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

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 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分: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);
没有你的指导,

真的找不到它

答案 2 :(得分:0)

您可以考虑使用cron作业逐个处理这些文件,然后将其输出存储在某处并在完成后检索输出。

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

显然,需求和要求可能意味着不可行。提高内存限制是一种选择,但如果您使用的是共享主机平台,则通常不会。它也只是意味着你绕过了问题,而不是解决它(即如果记录数量再次增加,问题就会出现)

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

答案 3 :(得分:0)

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

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

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

这是a great example of an Iterator class for XMLReader的链接。当我遇到这个问题时,我觉得这个课非常有帮助。我不得不做一些小的调整以满足我的需求,但它几乎是第一次工作。我希望它也适合你。