【发布时间】:2011-05-06 20:48:28
【问题描述】:
我正在尝试使用 simpleXML 在 php 中解析一个中等大小的 XML 文件 (6mb)。该脚本从 XML 文件中获取每条记录,检查它是否已被导入,如果尚未导入,则将该记录更新/插入到我自己的数据库中。
问题是我经常收到关于超出内存分配的致命错误:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 256 bytes) in /.../system/database/drivers/mysql/mysql_result.php on line 162
我通过使用以下行来增加最大内存分配避免了该错误(遵循here 的提示):
ini_set('memory_limit', '-1');
但是,然后我遇到了 60 秒的最大执行时间,并且无论出于何种原因,我的服务器(Mac OS X 上的 XAMPP)不会让我增加该时间(如果我运行脚本根本不会运行尝试包括这样的一行:)
set_time_limit(240);
然而,这一切似乎都非常低效;我不应该能够以某种方式分解文件并按顺序处理吗?在下面的控制器中,我有一个计数变量 ($cycle) 来跟踪我正在进行的记录,但我不知道如何实现它,它仍然不必处理整个 XML 文件。
控制器(我正在使用 CodeIgniter)具有以下基本结构:
$f = base_url().'data/data.xml';
if($data = file_get_contents($f))
{
$cycle = 0;
$xml = new SimpleXMLElement($data);
foreach($xml->person as $p)
{
//this makes a single call to db for single field based on id of record in XML file
if($this->_notImported('source',$p['id']))
{
//various process here, mainly breaking up the data for inserting into four different bales
}
$cycle++;
}
}
有什么想法吗?
已编辑
为了进一步了解我正在做的事情,我获取了每个元素和子元素的大部分属性并将它们插入到我的数据库中。例如,使用我的旧代码,我有这样的东西:
$insert = array('indiv_name' => $p['fullname'],
'indiv_first' => ($p['firstname']),
'indiv_last' => ($p['lastname']),
'indiv_middle' => ($p['middlename']),
'indiv_other' => ($p['namemod']),
'indiv_full_name' => $full_name,
'indiv_title' => ($p['title']),
'indiv_dob' => ($p['birthday']),
'indiv_gender' => ($p['gender']),
'indiv_religion' => ($p['religion']),
'indiv_url' => ($url)
);
根据使用 XMLReader 的建议(见下文),我该如何完成对主元素和子元素的属性的解析?
【问题讨论】:
标签: php xml memory-management