web-dev-qa-db-fra.com

Solution pour "Erreur fatale: Niveau d'imbrication de fonction maximal de '100' atteint, abandon!" dans PHP

J'ai créé une fonction qui trouve toutes les URL dans un fichier HTML et répète le même processus pour chaque contenu html lié aux URL découvertes. La fonction est récursive et peut continuer indéfiniment. Cependant, j'ai limité la récursivité en définissant une variable globale qui l'arrête après 100 récursions.

Cependant, php renvoie cette erreur:

Erreur fatale: niveau maximal d'imbrication de fonctions de '100' atteint, avorter! dans D:\wamp\www\crawler1\simplehtmldom_1_5\simple_html_dom.php en ligne 1355

ERROR

J'ai trouvé une solution ici: Augmentation du nombre maximal d'appels de fonctions d'imbrication mais cela ne fonctionne pas dans mon cas.

Je cite l'une des réponses du lien mentionné ci-dessus. S'il vous plaît, réfléchissez-y.

"Avez-vous installé Zend, IonCube ou xDebug? Dans l’affirmative, c’est probablement de là que vient cette erreur.

Je me suis heurté à cela il y a quelques années, et c'est finalement Zend qui a imposé cette limite, pas PHP. Bien sûr, le supprimer vous permettra de dépasser les 100 itérations, mais vous atteindrez éventuellement les limites de la mémoire. "

Existe-t-il un moyen d'augmenter le niveau d'imbrication maximal des fonctions en PHP?

118
Rafay

Une solution simple a résolu mon problème. Je viens de commenter cette ligne:

zend_extension = "d:/wamp/bin/php/php5.3.8/zend_ext/php_xdebug-2.1.2-5.3-vc9.dll

dans mon fichier php.ini. Cette extension limitait la pile à 100 alors je l'ai désactivée. La fonction récursive fonctionne maintenant comme prévu.

51
Rafay

Augmentez la valeur de xdebug.max_nesting_level dans votre php.ini: http://xdebug.org/docs/all_settings#max_nesting_level

134
Maxence

Plutôt que de rechercher des appels de fonction récursifs, utilisez un modèle de file d'attente pour aplatir la structure.

$queue = array('http://example.com/first/url');
while (count($queue)) {
    $url = array_shift($queue);

    $queue = array_merge($queue, find_urls($url));
}

function find_urls($url)
{
    $urls = array();

    // Some logic filling the variable

    return $urls;
}

Il y a différentes façons de le gérer. Vous pouvez garder plus d'informations si vous avez besoin d'informations sur l'origine ou les chemins parcourus. Il existe également des files d'attente distribuées pouvant fonctionner sur un modèle similaire.

43

Une autre solution consiste à ajouter xdebug.max_nesting_level = 200 dans votre php.ini.

40
bacar ndiaye

Plutôt que de désactiver xdebug, vous pouvez définir la limite supérieure telle que

xdebug.max_nesting_level = 500

23
shahinam

Essayez de regarder dans /etc/php5/conf.d/ pour voir s’il existe un fichier appelé xdebug.ini

max_nesting_level est 100 par défaut

S'il n'est pas défini dans ce fichier, ajoutez:

xdebug.max_nesting_level=300

à la fin de la liste de sorte qu'il ressemble à ceci

xdebug.remote_enable=on
xdebug.remote_handler=dbgp
xdebug.remote_Host=localhost
xdebug.remote_port=9000
xdebug.profiler_enable=0
xdebug.profiler_enable_trigger=1
xdebug.profiler_output_dir=/home/drupalpro/websites/logs/profiler
xdebug.max_nesting_level=300

vous pouvez ensuite utiliser @ Andrey's test avant et après avoir effectué ce changement pour voir s'il fonctionne.

php -r 'function foo() { static $x = 1; echo "foo ", $x++, "\n"; foo(); } foo();'
12
Lee Woodman

Allez dans votre fichier de configuration php.ini et changez la ligne suivante:

xdebug.max_nesting_level=100

à quelque chose comme:

xdebug.max_nesting_level=200
12
Yasssine ELALAOUI

sous Ubuntu avec PHP 5.59: 
obtenu à `: 

/etc/php5/cli/conf.d

et trouvez votre xdebug.ini dans ce répertoire, dans mon cas c'est 20-xdebug.ini

et ajoutez cette ligne `

xdebug.max_nesting_level = 200 


ou ca 

xdebug.max_nesting_level = -1

réglez-le sur -1 et vous n'avez pas à vous soucier de changer la valeur du niveau d'imbrication.

`

12
Gujarat Santana

est probablement arrivé à cause de xdebug.

Essayez de commenter la ligne suivante dans votre "php.ini" et redémarrez votre serveur pour recharger PHP.

";xdebug.max_nesting_level"

12
vandersondf

php.ini:

xdebug.max_nesting_level = -1

Je ne suis pas tout à fait sûr si la valeur dépassera un jour et atteindra -1, mais elle n'atteindra jamais -1 ou le niveau max_nesting_level sera assez élevé.

7
Martyn Shutt

Vous pouvez essayer d'imaginer l'imbrication en mettant en œuvre des travailleurs parallèles (comme dans l'informatique en cluster) au lieu d'augmenter le nombre d'appels de fonctions d'imbrication.

Par exemple: vous définissez un nombre limité de créneaux horaires (par exemple 100) et surveillez le nombre de "travailleurs" affectés à chaque/certains d'entre eux. Si des créneaux deviennent gratuits, vous mettez les travailleurs en attente "en eux".

6
tamasgal

Vous pouvez convertir votre code récursif en un code itératif, qui simule la récursivité. Cela signifie que vous devez insérer le statut actuel (URL, document, position dans le document, etc.) dans un tableau lorsque vous atteignez un lien et le sortir du tableau lorsque ce lien est terminé.

5
Yogu

Vérifiez la récursivité à partir de la ligne de commande:

php -r 'function foo() { static $x = 1; echo "foo ", $x++, "\n"; foo(); } foo();'

si résultat> 100 ALORS vérifier la limite de mémoire;

4
Andrey

Si vous utilisez Laravel, faites

composer update

Cela devrait être un travail.

3
<?php
ini_set('xdebug.max_nesting_level', 9999);
... your code ...

P.S. Remplacez 9999 par le nombre de votre choix.

2
cofirazak

Vous pouvez également modifier la fonction {debug} dans modifier.debug_print_var.php, afin de limiter sa récursivité aux objets.

Autour de la ligne 45, avant:

$results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
  . '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
  . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);

Après :

$max_depth = 10;
$results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
  . '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
  . ($depth > $max_depth ? 'Max recursion depth:'.(++$depth) : smarty_modifier_debug_print_var($curr_val, ++$depth, $length));

De cette façon, Xdebug se comportera toujours normalement: limiter la profondeur de récursivité dans var_dump, etc. Comme c'est un problème intelligent, pas un problème Xdebug!

0
theredled

Dans votre cas, il est clair que l'instance du robot d'exploration a davantage de limites Xdebug pour tracer les informations d'erreur et de débogage.

Mais, dans d’autres cas, des erreurs telles que PHP ou des fichiers centraux tels que les bibliothèques CodeIgniter créeront un tel cas et si vous augmentez même le paramètre de niveau de débogage x, il ne disparaîtra pas.

Alors, examinez attentivement votre code :).

Voici le problème dans mon cas.

J'ai eu une classe de service qui est la bibliothèque dans CodeIgniter. Avoir une fonction à l'intérieur comme ça.

 class PaymentService {

    private $CI;

    public function __construct() {

        $this->CI =& get_instance();

   }

  public function process(){
   //lots of Ci referencing here...
   }

Mon contrôleur comme suit:

$this->load->library('PaymentService');
$this->process_(); // see I got this wrong instead  it shoud be like 

L'appel de fonction sur la dernière ligne était erroné à cause de la faute de frappe, il aurait dû être comme ci-dessous:

$this->Payment_service->process(); //the library class name

Ensuite, je continuais à recevoir le message d'erreur de dépassement. Mais j'ai désactivé XDebug mais je n'ai pas aidé. De toute façon, veuillez vérifier votre nom de classe ou votre code pour un appel de fonction correct.

0
danielad

J'ai eu ce problème avec WordPress sur cloud9. Il s’avère que c’est le plugin W3 Caching. J'ai désactivé le plugin et cela a bien fonctionné.

0
sobeit

Une autre solution si vous exécutez un script php dans CLI (cmd)

Le fichier php.ini à éditer est différent dans ce cas. Dans mon installation de WAMP, le fichier php.ini chargé en ligne de commande est le suivant:

\wamp\bin\php\php5.5.12\php.ini

au lieu de\wamp\bin\Apache\apache2.4.9\bin\php.ini qui se charge lorsque php est lancé depuis le navigateur

0
Binod

J'ai eu une erreur quand j'installais beaucoup de plugins. Donc l'erreur 100 a montré notamment l'emplacement du dernier plugin que j'ai installé. C: dossier sur le lecteur C: tout était rentré dans l'ordre. Je pense que je dois limiter la quantité de plug-in que j'installe ou que j'ai activé. bonne chance, j'espère que cela aide

0
CalvinMD