php 达到最大函数嵌套级别“100”,中止
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10157649/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Maximum function nesting level of '100' reached, aborting
提问by Mike Boutin
I want to create a crawler who take the informations of all pages one by one from number 0 to 10 000 000. I don't matter how much time it takes. I just want it works. Here is the error i obtain
我想创建一个爬虫,将所有页面的信息从 0 到 10 000 000 一一获取。我不管需要多少时间。我只是想让它起作用。这是我得到的错误
Fatal error: Maximum function nesting level of '100' reached, aborting! in D:\wamp\www\crawler\index.php on line 25
The line 25 is
第 25 行是
$htmlstr = (string)$this->curlGet($url);
And there is my complete script.
还有我的完整脚本。
Thank you for your help !
感谢您的帮助 !
header('Content-Type: text/html; charset=utf-8');
ini_set('max_input_nesting_level','100000');
ini_set('max_execution_time','100000');
class crawler{
private $url;
private $page;
private $bothurl;
private $innerDom = null;
public $prop;
public $entry;
function __construct($entry){
$this->entry = $entry;
$this->bothurl = array('http://www.remax-quebec.com/fr/inscription/Q/'.$entry.'.rmx','http://www.remax-quebec.com/en/inscription/Q/'.$entry.'.rmx');
$this->scan();
}
private function scan(){
$i =0;
foreach($this->bothurl as $url){
$this->url = $url;
$this->lang = ($i==0)?'fr':'en';
$htmlstr = (string)$this->curlGet($url);
$dom = new DOMDocument;
@$dom->loadHTML($htmlstr);
$this->page = $dom;
$this->htmlInfos();
$this->getInfos();
$i++;
}
}
private function htmlInfos(){
$divs = $this->page->getElementsByTagName('div');
foreach($divs as $div){
if($div->hasAttribute('class') && $div->getAttribute('class') == 'bloc specs'){
$innerDom = new DOMDocument();
@$innerDom->loadHTML($this->innerHTML($div));
$this->innerDom = $innerDom;
}
}
if($this->innerDom === null) $this->changeEntry();
}
private function getInfos(){
$sect = 0;
foreach($this->innerDom->getElementsByTagName('div') as $div){
# obtenir la description
$this->getDesc($div->getAttribute('class'),$div);
# obtenir les caractéristiques
$this->getCaract($div->getAttribute('class'),$div);
# obtenir les informations interieur, exterieur et evaluation
if($div->getAttribute('class') == 'section deux-colonnes'){
switch($sect){
case 0: $this->getSpecInfos($div,'interieur'); break;
case 1: $this->getSpecInfos($div,'exterieur'); break;
case 2: $this->getSpecInfos($div,'evaluation'); break;
case 3: $this->getSpecInfos($div,'equipement'); break;
case 4: $this->getSpecInfos($div,'services'); break;
}
$sect++;
}else if($div->getAttribute('class') == 'section'){
# obtenir les détails des pièces
foreach($div->getElementsByTagName('table') as $table){
if($table->getAttribute('class') == 'details-pieces'){
$this->detailPieces($table);
}
}
}
}
}
private function getDesc($class,$obj){
if($class == 'section description'){
$p = $obj->getElementsByTagName('p')->item(0);
$text = (string)$p->nodeValue;
$this->prop[$this->lang]['description'] = $text;
}
}
private function getCaract($class,$obj){
if($class == 'section characteristiques'){
foreach($obj->getElementsByTagName('div') as $div){
if(substr($div->getAttribute('class'),0,4) == "item"){
$text = (string)$div->nodeValue;
$this->prop[$this->lang]['caracteritiques'][substr($div->getAttribute('class'),5)] = $text;
}
}
}
}
private function getSpecInfos($obj,$nomInfo){
foreach($obj->getElementsByTagName('table') as $table){
foreach($table->getElementsByTagName('tr') as $tr){
$name = $tr->getElementsByTagName('td')->item(0);
$value = $tr->getElementsByTagName('td')->item(1);
$name = substr((string)$name->nodeValue,0,-2);
$value = (string)$value->nodeValue;
$this->prop[$this->lang][$nomInfo][$this->noAccents($name)] = $value;
}
}
}
private function detailPieces($obj){
$tbody = $obj->getElementsByTagName('tbody')->item(0);
foreach($tbody->getElementsByTagName('tr') as $tr){
$name = $tr->getElementsByTagName('td')->item(0);
$name = (string)$name->nodeValue;
$level = $tr->getElementsByTagName('td')->item(1);
$level = (string)$level->nodeValue;
$dimensions = $tr->getElementsByTagName('td')->item(2);
$dimensions = (string)$dimensions->nodeValue;
$floor = $tr->getElementsByTagName('td')->item(3);
$floor = (string)$floor->nodeValue;
$desc = $tr->getElementsByTagName('td')->item(4);
$desc = (string)$desc->nodeValue;
$this->prop[$this->lang]['pieces'][$this->noAccents($name)]['etage'] = $level;
$this->prop[$this->lang]['pieces'][$this->noAccents($name)]['dimensions'] = $dimensions;
$this->prop[$this->lang]['pieces'][$this->noAccents($name)]['revetement'] = $floor;
$this->prop[$this->lang]['pieces'][$this->noAccents($name)]['description'] = $desc;
}
}
private function innerHTML($element){
$innerHTML = "";
$children = $element->childNodes;
foreach ($children as $child)
{
$tmp_dom = new DOMDocument();
$tmp_dom->appendChild($tmp_dom->importNode($child, true));
$innerHTML.=trim($tmp_dom->saveHTML());
}
return $innerHTML;
}
private function noAccents($value){
$string= strtr($chaine,"àá????àáa???òó????òó????èéê?èéê???ìí??ìí??ùú?üùú?ü???","aaaaaaaaaaaaooooooooooooeeeeeeeecciiiiiiiiuuuuuuuuynn");
}
private function changeEntry(){
$this->entry++;
echo $this->entry;
$this->scan();
}
private function curlGet($url){
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_ENCODING, "gzip");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
$data = curl_exec($curl);
curl_close($curl);
return $data;
}
}
$entry = 8678057;
$crawler = new crawler($entry);
echo '<pre>';
print_r($crawler->prop);
echo '</pre>';
回答by Martin.
Assuming you're using xdebug, you can set your own limit with
假设您使用的是 xdebug,您可以设置自己的限制
ini_set('xdebug.max_nesting_level', $limit)
回答by medina
changes the file /etc/mysql/my.cnf parameter to something like that max_allowed_packet = 512M
将文件 /etc/mysql/my.cnf 参数更改为类似 max_allowed_packet = 512M 的内容
Get sure you've got xdebug installed (use phpinfo()) and then change the file /etc/php5/fpm/php.ini adding or editing the line : xdebug.max_nesting_level=1000
确保您已经安装了 xdebug(使用 phpinfo()),然后更改文件 /etc/php5/fpm/php.ini 添加或编辑以下行:xdebug.max_nesting_level=1000
Restart both services sudo service mysql restart sudo service php5-fpm restart
重启两个服务 sudo service mysql restart sudo service php5-fpm restart
If it doesn't work you can still set those two parameters to false at /etc/php5/fpm/php.ini xdebug.remote_autostart=0 xdebug.remote_enable=0
如果它不起作用,您仍然可以在 /etc/php5/fpm/php.ini xdebug.remote_autostart=0 xdebug.remote_enable=0 将这两个参数设置为 false
回答by Nicolas
In my case, it was related to composer. Some vendors were updated in the composer.jsonfile, but I forgot to run the commands composer updatenor composer install. The system generated a cascade of errros, which was causing this 'maximum nested level'.
就我而言,它与作曲家有关。一些供应商在composer.json文件中进行了更新,但我忘记运行命令composer update或composer install。系统产生了一连串的错误,这导致了这个“最大嵌套级别”。
After executing those commands, the problem was fixed
执行这些命令后,问题就解决了
回答by Frank Miller
Assuming you didn't make a drop-dead halt mistake, just change the limit of xdebug.
假设你没有犯一个直接停止的错误,只需改变 xdebug 的限制。
I sloved this problem by changed the xdebug.inifile. (In my mac, the path is /usr/local/php5-5.6.17-20160108-103504/php.d/50-extension-xdebug.ini, maybe yours would be a little different. )
我通过更改xdebug.ini文件解决了这个问题。(在我的 mac 中,路径是/usr/local/php5-5.6.17-20160108-103504/php.d/50-extension-xdebug.ini,也许你的会有点不同。)
Add a new line at the bottom of xdebug.ini file:
在 xdebug.ini 文件的底部添加一个新行:
xdebug.max_nesting_level=500
xdebug.max_nesting_level=500
Remember: You must change the xdebug.ini corresponding to the php you are using. For example, if you installed php5 and xampp in your computer, you need to figure out which php you're using.
请记住:您必须更改与您正在使用的 php 相对应的 xdebug.ini。例如,如果您在计算机中安装了 php5 和 xampp,则需要弄清楚您使用的是哪个 php。

