147 votes

Solution pour "Fatal error : Le niveau maximal d'imbrication des fonctions de '100' a été atteint, abandon de l'opération" en PHP

J'ai créé une fonction qui trouve toutes les URLs dans un fichier html et répète le même processus pour chaque contenu html lié aux URLs découvertes. La fonction est récursive et peut se poursuivre à l'infini. Cependant, j'ai mis une limite à la récursion en définissant une variable globale qui fait que la récursion s'arrête après 100 récursions.

Cependant, php renvoie cette erreur :

Erreur fatale : Le niveau maximal d'imbrication des fonctions de '100' est atteint, abandon ! in D:\wamp\www\crawler1\simplehtmldom_1_5\simple_html_dom.php sur la ligne 1355

ERROR

J'ai trouvé une solution ici : Augmentation de la limite d'appels de fonctions imbriquées mais cela ne fonctionne pas dans mon cas.

Je cite l'une des réponses du lien mentionné ci-dessus. Veuillez en tenir compte.

"Avez-vous installé Zend, IonCube ou xDebug ? Si c'est le cas, c'est probablement à partir de là que vous obtenez cette erreur.

J'ai rencontré ce problème il y a quelques années, et c'est Zend qui a mis cette limite, pas PHP. Bien sûr, l'enlever vous permettra de dépasser les 100 itérations, mais vous finirez par atteindre les limites de mémoire."

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

2 votes

Aussi : PHP n'a pas de limite pour les appels de fonctions imbriquées, ce doit être une extension que vous utilisez qui cause ce problème.

0 votes

@Abel Je suis sûr que mon code ne comporte aucune erreur. Il existe une variable statique qui incrémente sa valeur de un à chaque appel récursif. Si cette variable est inférieure à 100, les appels récursifs se poursuivent jusqu'à ce que la variable atteigne 100. Je veux dire que la variable atteignant 100 est en fait le cas de base. Alors que l'erreur survient avant 100 récursions. Et comme vous avez mentionné qu'une extension peut être à l'origine de ce problème, je voudrais mentionner que j'utilise des fonctions de simple_html_dom.php. Si vous avez une idée sur simple_html_dom.php, veuillez m'aider à cet égard. Veuillez vous référer à la question mise à jour.

7 votes

C'est une erreur de xdebug. D'après la capture d'écran, il est visible que vous utilisez xdebug. Vous pouvez désactiver ce paramètre ici : xdebug.max_nesting_level ou indiquer la taille du niveau d'imbrication.

159voto

Maxence Points 5619

Augmenter la valeur de xdebug.max_nesting_level dans votre php.ini

0 votes

Pouvez-vous m'expliquer comment vous faites ?

6 votes

@A.L Vous modifiez votre fichier php.ini et vous ajoutez ou modifiez la ligne xdebug.max_nesting_level dans la section XDebug.

3 votes

Cependant, s'il s'agit d'un environnement de production, consultez la réponse acceptée, qui consiste à désactiver xdebug dans cet environnement.

61voto

Mohammad Rafay Aleem Points 1384

Une solution simple a résolu mon problème. J'ai simplement commenté cette ligne :

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

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

4 votes

Donc, finalement, c'était l'extension XDebug après tout... Bon à savoir. Dans deux jours, vous pourrez accepter votre propre réponse comme réponse acceptée, si vous le souhaitez (et jetez un coup d'œil à vos questions précédentes, la plupart d'entre elles n'ont pas de réponse acceptée).

68 votes

Gérer la récursion excessive est sûrement mieux que de simplement désactiver le contrôle.

7 votes

C'est une approche maladroite. Les réponses ci-dessus, qui mentionnent la variable permettant d'ajuster la profondeur maximale de la pile, constituent une meilleure approche.

45voto

bacar ndiaye Points 199

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

10 votes

Il est également possible de le faire en php, par exemple dans le fichier de configuration de votre projet. ini_set('xdebug.max_nesting_level', 200);

0 votes

@htxryan Je ne suis pas un expert mais c'est dû à votre pile d'appel trop "profonde" (trop de fonctions appelant d'autres fonctions). Le scénario typique où cela se produit est avec une fonction récursive. Le paramètre est très probablement là pour éviter une récursion "hors de contrôle" due à un bug dans le code.

0 votes

@svassr vous pourriez envisager d'ajouter cette astuce dans une réponse séparée ou de l'ajouter à une réponse existante, elle m'a été utile mais j'ai failli la manquer dans les commentaires.

43voto

Plutôt que de recourir à des appels de fonctions 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 la trace de plus d'informations si vous avez besoin d'un aperçu de l'origine ou des chemins traversés. Il existe également des files d'attente distribuées qui peuvent fonctionner sur un modèle similaire.

5 votes

Avec SPL, vous n'avez pas besoin de réinventer la queue : php.net/manual/fr/class.splqueue.php

1 votes

SPL Queue pourrait offrir un peu plus de vitesse, mais je préfère m'en tenir aux tableaux pour la plupart des tâches simples. push/pop/shift/unshift sont tous fournis.

1 votes

C'est la bonne réponse. Évitez de modifier les valeurs par défaut. Essayez d'optimiser votre code.

23voto

shahinam Points 402

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

xdebug.max_nesting_level=500

0 votes

@SebastianMach : et, étonnamment, des années après, aussi. :) (Genre quatre fois de plus, ou à peu près. Non seulement les gens ne lisent plus, mais ils ne scrollent même plus).

1 votes

@Sz. : Wow, quelle explosion du passé :P Incroyablement choquant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X