Решение для "Неустранимая ошибка: максимальный уровень гнездования функции" 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, поэтому я отключил его. Рекурсивная функция теперь работает как ожидаемая.

Ответ 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('&nbsp;', $depth * 2)
  . '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
  . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);

После:

$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));

Таким образом, Xdebug будет вести себя нормально: ограничьте глубину рекурсии в var_dump и так далее. Поскольку это сложная проблема, а не Xdebug!