【发布时间】:2013-08-19 14:40:00
【问题描述】:
我正在尝试从许多 html 文件中提取数据文件。为了快速完成,我不使用 DOM 解析器,而是使用简单的strpos()。如果我从大约 200000 个文件生成,一切顺利。但是如果用更多的文件(300000)来做,它什么也不输出,并且会产生这种奇怪的效果:
看下图。 (上面是 CPU)在第一个(标记为红色)阶段,输出文件大小正在增长,一切似乎都很好。之后(标记为橙色)文件大小变为零并且内存使用量正在增长。 (一切都是两次,因为我在中场休息时重新开始计算)
我忘了说我使用 WAMP。
我已经厌倦了未设置的变量,将循环放入函数中,使用 implode 而不是连接字符串,使用 fopen 而不是 filegetcontents 和垃圾收集......
什么是第二阶段?我是不是没记性了?是否有一些我不知道的限制(max_execution_time,memory_limit - 已被忽略)?为什么这个小程序会占用这么多内存?
这里是代码。
$datafile = fopen("meccsek2b.jsb", 'w');
for($i=0;$i<100000;$i++){
$a = explode('|',$data[$i]);
$file = "data2/$mid.html";
if(file_exists($file)){
$c = file_get_contents($file);
$o = 0;
$a_id = array();
$a_h = array();
$a_d = array();
$a_v = array();
while($o = strpos($c,'<a href="/test/',$o)){
$o = $o+15;
$a_id[] = substr($c,$o,strpos($c,'/',$o)-$o);
$o = strpos($c,'val_h="',$o)+7;
$a_h[] = substr($c,$o,strpos($c,'"',$o)-$o);
$o = strpos($c,'val_d="',$o)+7;
$a_d[] = substr($c,$o, strpos($c,'"',$o)-$o);
$o = strpos($c,'val_v="',$o)+7;
$a_v[] = substr($c,$o,strpos($c,'"',$o)-$o);
}
fwrite($datafile,
$mid.'|'.
implode(';',$a_id).'|'.
implode(';',$a_h).'|'.
implode(';',$a_d).'|'.
implode(';',$a_v).
PHP_EOL);
}
}
fclose($datafile);
Apache error log. (expires in 30 days)
我想我找到了问题:
因为strpos() 返回了 0,所以出现了无限循环。
分配的内存大小一直在增长,直到出现异常:
PHP Fatal error: Out of memory
Ensino 的笔记对使用 命令行 非常有用,最终将我带到了this question。
【问题讨论】:
-
如果是内存问题,我认为它会在您的错误日志中生成一个致命错误,对吧?另外,您是否尝试过在迭代时打开/关闭 $datafile?也许您可以尝试使用 file_get_contents 将其作为套接字打开?
-
你能显示你用来打开和关闭输出文件的代码吗?您是否尝试从命令行运行脚本?
-
@AaronSaray PHP 错误日志为空。我打开/关闭它但没有修改。如何将其作为套接字打开?
-
我已插入 apache 错误日志。
-
@Enzino 代码已更新。我总是从浏览器打开脚本。
标签: php memory-management file-io wamp