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
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?
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.
Augmentez la valeur de xdebug.max_nesting_level dans votre php.ini: http://xdebug.org/docs/all_settings#max_nesting_level
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.
Une autre solution consiste à ajouter xdebug.max_nesting_level = 200
dans votre php.ini.
Plutôt que de désactiver xdebug, vous pouvez définir la limite supérieure telle que
xdebug.max_nesting_level = 500
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();'
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
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.
`
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"
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é.
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".
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é.
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;
Si vous utilisez Laravel, faites
composer update
Cela devrait être un travail.
<?php
ini_set('xdebug.max_nesting_level', 9999);
... your code ...
P.S. Remplacez 9999 par le nombre de votre choix.
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(' ', $depth * 2)
. '<b> ->' . strtr($curr_key, $_replace) . '</b> = '
. smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
Après :
$max_depth = 10;
$results .= '<br>' . str_repeat(' ', $depth * 2)
. '<b> ->' . 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!
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.
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é.
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
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