【发布时间】:2012-01-27 19:19:59
【问题描述】:
我的脚本是一个蜘蛛,它检查页面是“链接页面”还是“信息页面”。 如果页面是“链接页面”,那么它会以递归方式继续(如果你愿意,也可以是树) 直到找到“信息页”。
我试图让脚本递归,这很容易,但我一直收到错误:
致命错误:允许的内存大小为 33554432 字节已用尽(试图 在第 1316 行的 /srv/www/loko/simple_html_dom.php 中分配 39 个字节)
有人告诉我,我必须使用 for 循环方法,因为无论我是否使用 unset() 函数,脚本都不会释放内存,而且我只需要循环三个级别通过所以这是有道理的。但是在我更改脚本后,错误再次发生,但也许我可以释放 现在还记得吗?
这里有东西要死,请帮我毁掉一个人!
set_time_limit(0);
ini_set('memory_limit', '256M');
require("simple_html_dom.php");
$thelink = "http://www.somelink.com";
$html1 = file_get_html($thelink);
$ret1 = $html1->find('#idTabResults2');
// first inception level, we know page has only links
if (!$ret1){
$es1 = $html1->find('table.litab a');
//unset($html1);
$countlinks1 = 0;
foreach ($es1 as $aa1) {
$links1[$countlinks1] = $aa1->href;
$countlinks1++;
}
//unset($es1);
//for every link in array do the same
for ($i = 0; $i < $countlinks1; $i++) {
$html2 = file_get_html($links1[$i]);
$ret2 = $html2->find('#idTabResults2');
// if got information then send to DB
if ($ret2){
pullInfo($html2);
//unset($html2);
} else {
// continue inception
$es2 = $html2->find('table.litab a');
$html2 = null;
$countlinks2 = 0;
foreach ($es2 as $aa2) {
$links2[$countlinks2] = $aa2->href;
$countlinks2++;
}
//unset($es2);
for ($j = 0; $j < $countlinks2; $j++) {
$html3 = file_get_html($links2[$j]);
$ret3 = $html3->find('#idTabResults2');
// if got information then send to DB
if ($ret3){
pullInfo($html3);
} else {
// inception level three
$es3 = $html3->find('table.litab a');
$html3 = null;
$countlinks3 = 0;
foreach ($es3 as $aa3) {
$links3[$countlinks3] = $aa3->href;
$countlinks3++;
}
for ($k = 0; $k < $countlinks3; $k++) {
echo memory_get_usage() ;
echo "\n";
$html4 = file_get_html($links3[$k]);
$ret4 = $html4->find('#idTabResults2');
// if got information then send to DB
if ($ret4){
pullInfo($html4);
}
unset($html4);
}
unset($html3);
}
}
}
}
}
function pullInfo($html)
{
$tds = $html->find('td');
$count =0;
foreach ($tds as $td) {
$count++;
if ($count==1){
$name = html_entity_decode($td->innertext);
}
if ($count==2){
$address = addslashes(html_entity_decode($td->innertext));
}
if ($count==3){
$number = addslashes(preg_replace('/(\d+) - (\d+)/i', '$2$1', $td->innertext));
}
}
unset($tds, $td);
$name = mysql_real_escape_string($name);
$address = mysql_real_escape_string($address);
$number = mysql_real_escape_string($number);
$inAlready=mysql_query("SELECT * FROM people WHERE phone=$number");
while($e=mysql_fetch_assoc($inAlready))
$output[]=$e;
if (json_encode($output) != "null"){
//print(json_encode($output));
} else {
mysql_query("INSERT INTO people (name, area, phone)
VALUES ('$name', '$address', '$number')");
}
}
这是内存大小增长的图片:
【问题讨论】:
-
require("simple_html_dom.php");会不会在这里发生?
-
@NSjonas 你是什么意思?和 RPM 我在 bash 中运行它
-
顺便说一下,您的 SQL 查询容易受到 SQL 注入的攻击。
-
请注意,您可以将
$data1 = file_get_contents($thelink); $html1 = str_get_html($data1);替换为$html1 = file_get_html($thelink);。这样可以避免在内存中保留每个文档的多个表示形式。 -
您可能还想在使用完这三个文档后分别释放它们。
标签: php memory memory-leaks memory-management