Решение для "Неустранимая ошибка: максимальный уровень гнездования функции" 100 "достигнут, прерывается!" в PHP
Я создал функцию, которая находит все URL-адреса в html файле и повторяет тот же процесс для каждого содержимого html, связанного с обнаруженными URL-адресами. Функция рекурсивна и может продолжаться бесконечно. Однако я поставил ограничение на рекурсию, установив глобальную переменную, которая заставит рекурсию остановиться после 100 рекурсий.
Однако php возвращает эту ошибку:
Неустранимая ошибка: максимальный уровень вложенности функции "100" достигнут, прерывание! в D:\wamp\www\crawler1\simplehtmldom_1_5\simple_html_dom.php on line 1355
![ERROR]()
Я нашел решение здесь: Увеличение ограничений вызовов функций вложенности, но это не работает в моем случае.
Я цитирую один из ответов из упомянутой выше ссылки. Пожалуйста, подумайте об этом.
"У вас установлены Zend, IonCube или xDebug? Если это так, вероятно, вы получаете эту ошибку.
Я столкнулся с этим несколько лет назад, и в конечном итоге Zend поставил этот предел, а не PHP. Конечно, его удаление позволит вам пройти 100 итераций, но в конечном итоге вы попадете в пределы памяти.
Есть ли способ увеличить максимальный уровень вложенности функций в PHP
Ответы
Ответ 1
Простое решение решило мою проблему. Я просто прокомментировал эту строку:
zend_extension = "d:/wamp/bin/php/php5.3.8/zend_ext/php_xdebug-2.1.2-5.3-vc9.dll
в моем php.ini
файле. Это расширение ограничивало стек до 100
, поэтому я отключил его. Рекурсивная функция теперь работает как ожидаемая.
Ответ 2
Увеличьте значение xdebug.max_nesting_level в вашем php.ini: http://xdebug.org/docs/all_settings#max_nesting_level
Ответ 3
Вместо того, чтобы искать рекурсивные вызовы функций, работайте с моделью очереди, чтобы сгладить структуру.
$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;
}
Существуют разные способы обработки. Вы можете отслеживать дополнительную информацию, если вам нужна информация о происхождении или пройденных маршрутах. Существуют также распределенные очереди, которые могут работать с аналогичной моделью.
Ответ 4
Другим решением является добавить xdebug.max_nesting_level = 200
в php.ini
Ответ 5
Вместо того, чтобы отключать xdebug, вы можете установить более высокий предел, например
xdebug.max_nesting_level = 500
Ответ 6
Также можно исправить это непосредственно в php, например, в файле конфигурации вашего проекта.
ini_set('xdebug.max_nesting_level', 200);
Ответ 7
вероятно, произошло из-за xdebug.
Попробуйте комментировать следующую строку в вашем "php.ini" и перезапустите сервер, чтобы перезагрузить PHP.
";xdebug.max_nesting_level"
Ответ 8
Попробуйте найти в файле /etc/php 5/conf.d/, если есть файл с именем xdebug.ini
max_nesting_level по умолчанию 100.
Если он не установлен в этом файле, добавьте:
xdebug.max_nesting_level=300
до конца списка, чтобы он выглядел следующим образом:
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
вы можете использовать тест @Andrey до и после внесения этого изменения, чтобы убедиться, что он работает.
php -r 'function foo() { static $x = 1; echo "foo ", $x++, "\n"; foo(); } foo();'
Ответ 9
Перейдите в конфигурационный файл php.ini и измените следующую строку:
xdebug.max_nesting_level=100
к чему-то вроде:
xdebug.max_nesting_level=200
Ответ 10
на Ubuntu с использованием PHP 5.59:
добрался до `:
/etc/php5/cli/conf.d
и найдите xdebug.ini в этом каталоге, в моем случае 20-xdebug.ini
и добавьте эту строку `
xdebug.max_nesting_level = 200
или этот
xdebug.max_nesting_level = -1
установите значение -1, и вам не придется беспокоиться об изменении значения уровня вложенности.
`
Ответ 11
php.ini:
xdebug.max_nesting_level = -1
Я не совсем уверен, будет ли значение переполняться и достигнет -1, но оно никогда не достигнет -1, или оно установит max_nesting_level довольно высоко.
Ответ 12
Вы можете попытаться отбросить вложенность путем реализации параллельных рабочих (например, в кластерных вычислениях) вместо увеличения числа вызовов функций вложенности.
Например: вы определяете ограниченное количество слотов (например, 100) и отслеживаете количество "рабочих", назначенных каждому/некоторым из них. Если какие-либо слоты становятся свободными, вы помещаете в них ожидающих работников.
Ответ 13
Вы можете преобразовать ваш рекурсивный код в итеративный код, который имитирует рекурсию. Это означает, что вам нужно нажать текущее состояние (url, document, position in document и т.д.) В массив, когда вы достигнете ссылки, и вытащите его из массива, когда эта ссылка закончится.
Ответ 14
Проверьте рекурсию из командной строки:
php -r 'function foo() { static $x = 1; echo "foo ", $x++, "\n"; foo(); } foo();'
если результат > 100 ТОГДА проверьте ограничение памяти;
Ответ 15
Если вы используете Laravel, сделайте
composer update
Это должно быть работа.
Ответ 16
<?php
ini_set('xdebug.max_nesting_level', 9999);
... your code ...
PS Измените 9999 на любое количество, которое вы хотите.
Ответ 17
В вашем случае определенно экземпляр искателя имеет больше ограничений Xdebug для отслеживания ошибок и отладки информации.
Но в других случаях такие ошибки, как на PHP или основные файлы, такие как библиотеки CodeIgniter, создадут такой случай, и если вы даже увеличите настройку уровня x-debug, он не исчезнет.
Итак, внимательно изучите свой код:).
Вот проблема в моем случае.
У меня был класс сервиса, который является библиотекой в CodeIgniter. Наличие внутри такой функции.
class PaymentService {
private $CI;
public function __construct() {
$this->CI =& get_instance();
}
public function process(){
//lots of Ci referencing here...
}
Мой контроллер:
$this->load->library('PaymentService');
$this->process_(); // see I got this wrong instead it shoud be like
Вызов функции на последней строке был неправильным из-за опечатки, вместо этого он должен был выглядеть следующим образом:
$this->Payment_service->process(); //the library class name
Затем я продолжал получать сообщение об ошибке превышения. Но я отключил XDebug, но не помог. В любом случае, пожалуйста, проверьте имя класса или код для правильного вызова функции.
Ответ 18
У меня была ошибка, когда я устанавливал много плагинов. Таким образом, ошибка 100 показала, включая местоположение последнего плагина, в котором я установил C:\wamp\www\mysite\wp-content\plugins\ "...", поэтому я удалил эту папку с плагином на диске C: тогда все вернулось к нормальному. Я думаю, что мне нужно ограничить количество подключаемого модуля, который я устанавливаю или активировал. Удачи, надеюсь, что это поможет
Ответ 19
У меня была эта проблема с WordPress на cloud9. Оказывается, это был плагин W3 Caching. Я отключил плагин, и он работал нормально.
Ответ 20
Другое решение, если вы используете php script в CLI (cmd)
В этом случае файл php.ini, который нуждается в редактировании, отличается. В моей установке WAMP файл php.ini, загруженный в командной строке:
\wamp\bin\php\php5.5.12\php.ini
вместо\wamp\bin\apache\apache2.4.9\bin\php.ini, который загружается при запуске php из браузера
Ответ 21
Вы также можете изменить функцию {debug} в файле modifier.debug_print_var.php, чтобы ограничить ее рекурсию на объекты.
Вокруг строки 45, до:
$results .= '<br>' . str_repeat(' ', $depth * 2)
. '<b> ->' . strtr($curr_key, $_replace) . '</b> = '
. smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
После:
$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));
Таким образом, Xdebug будет вести себя нормально: ограничьте глубину рекурсии в var_dump и так далее.
Поскольку это сложная проблема, а не Xdebug!