2012-11-02 51 views
0

我一直在使用使用simplexml_load_file解析15000个记录的XML文件,它工作正常,但是当我试图用许多文件工作的每个人的15000它给了我这个errorPHP使用simplexml_load_file在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']; 
           } 
         } 
} 

我需要一些免费的解析完成后,请注意,有许多文件时,会发生的问题,我尝试过两个文件,并没有问题

+0

有更清楚这个代码比你向我们展示什么,你不给我们太多去。最好我可以告诉你,你已经包含了什么,你可以使用['unset()'](http://ca2.php.net/manual/en/function.unset.php)重新完成他们从内存中删除它们。 – Sammitch

+0

代码中的内容会导致内存错误?换句话说,您是否能够在第一行中加载文档,或者您能够在看到错误之前以部分方式执行脚本? –

+1

你甚至探索过谷歌?如果你不需要发布足够的代码,至少将内存限制加倍。 'ini_set('memory_limit','256M');' – wesside

回答

0

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

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

很明显,需求和要求可能意味着不可行。提高内存限制是一种选择,但通常不适用于共享主机平台。这也只是意味着你绕过问题,而不是解决它(即,如果记录的数量再次增加,这个问题会回来)

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

+0

其实这是代码,我所做的只是循环遍历目录并开始处理文件并将所有内容放入数据库中,但我没有因为它与问题没有任何关系 – Ivan

+0

如果这就是我看到没有理由你不能为他们建立一个小队列,处理一个文件,将它添加到数据库,然后结束脚本和另一个自动开始如果你的cron检测到有新文件需要处理。而不是试图一次性在一个脚本中完成它们。 –

+0

我试图取消设置$ xml,看起来像是在工作 – Ivan

2

不要使用大文件的SimpleXML .. 使用XML DOM对象。

你可以使用像SAX或XMLReader的或其他第三方的一些先进的工具来分析数据。

+1

+1。 SimpleXML将整个事物加载到内存中。难怪当你给它一个大文件时它会炸毁。 – Spudley

0

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

相反,您需要使用XMLReader类。这个类每次读取一个XML元素,并在阅读后抛出。这意味着您一次只能在内存中获得最少的数据。

使用这个类的简便方法是通过在迭代器类加以包装。这意味着您可以使用foreach()来遍历元素,就像它们全部被加载一样。

下面是a great example of an Iterator class for XMLReader的链接。当我遇到这个问题时,我发现这门课非常有帮助。为了满足我的需求,我不得不做一些小的调整,但第一次工作起来非常有效。我希望它也适用于你。

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); 

止跌”前吨真的发现它没有你的指导