如何在PHP中循环循环?

时间:2010-03-11 00:14:23

标签: php

有没有办法在php中循环循环?

如果我有一个函数,例如,我可以循环这个函数吗?

在php6中有goto。但你怎么能在php5中这样做?

function getLinks($link) {
    // step 1: if $link got links, add them in a array
    // step 2: iterate array of links
    // step 3: save current link
    // step 4: check if current link got links, if it has, run $this->getLinks($link)
}

在步骤4中我需要使用函数getLinks。正如您所见,我想制作一个抓取每个链接并保存它们的爬虫。

有人做了类似的事情,试图循环/抓取所有级别的链接吗?

我想我需要Goto功能,但有没有办法在php 5中完成这个?

我不知道我怎么能这样做...提前谢谢!

6 个答案:

答案 0 :(得分:7)

是的,这是可能的。如果您在方法的中调用相同的方法,则使用的是recursion。关于递归循环要记住的重要事项之一是确保添加一个 base 大小写以停止循环,否则你将继续循环并且这不好。

我建议不要去递归路线,这需要很多开销,应该是你的最后一招。使用while循环应该会得到类似的结果。

答案 1 :(得分:1)

它被称为递归函数(只是在函数体中再次调用函数)。但是,如果你正在构建一个爬虫,我会提醒你表现得很好。你可以看看http://www.robotstxt.org/。类似于同一域上的请求之间的时间长度可能会受到所有者robots.txt文件的限制。如果你表现不好,你可能会被许多系统管理员禁止。

答案 2 :(得分:1)

我认为您不需要goto来执行此任务。要迂腐,你不需要goto。永远! Böhm-Jacopini:)

也许使用一些代码我会更精确但是,假设 $ links 是一个网址,并且你有一个名为 harvestPage 的函数,它获取的网址是一个页面并返回一个包含它包含的所有链接(url)的数组,你也不必诉诸递归。 管道(FIFO)就足够了:

function getLinks($link) {
 $linksToCrawl = harvestPage($links)
  while (count($linksToCrawl)) {
    $currentLink = array_shift($linksToCrawl);
    save($CurrentLink);
    $linksToCrawl = array_merge($linksToCrawl, harvestPage($currentLink));
  }
}

记住你也应该检查循环引用(也可能是robot.txt :)。

答案 3 :(得分:1)

像...一样的东西。

function stuff($link,$links=Array()){
  if (($contents=@file_get_contents($link))!==false){
    preg_match_all('@https?://[^"\'}{\[\]<>\s]{3,255}@i',$contents,$linkDump);
    $links=array_merge($links,$linkDump[0]);
  }
  stuff(array_shift($links),$links);
}
stuff('http://www.foxnews.com/'); //packet them all you want while testing ;)

最好使用curl类并使用回调进行解析,直到没有更多的链接,而不是递归。您需要过滤掉css,js,pics等,并确保不要重复执行相同的链接。 file_get_contents是愚蠢但很好'因为让我用简短的方式写它并且仍然有效。

答案 4 :(得分:0)

改为使用while()循环,break退出。

while(1)
{
  ....
};

答案 5 :(得分:0)

你可以在评论中写下你所写的内容:

function getLinks($link) {
    step 1: Parse the page and get the list of links ==> $listLinks
    loop - step 2: iterate over $listLinks (currLink = $currLink)
        step 3: $globalListOfLinks[count($globalListOfLinks)] = $currLink
        step 4: $this->getLinks($link);
    end loop;
}

当然你必须要管理递归次数,你不能递归到太远,所以,你也可以有一个深度变量并将它与$ link一起传递。如果你是&gt;一些深度,回归;