it-swarm.com.ru

Решение для "Фатальная ошибка: достигнут максимальный уровень вложенности функции '100', прерывание!" в PHP

Я сделал функцию, которая находит все URL-адреса в HTML-файле и повторяет один и тот же процесс для каждого HTML-контента, связанного с обнаруженными URL-адресами. Функция рекурсивная и может продолжаться бесконечно. Однако я наложил ограничение на рекурсию, установив глобальную переменную, которая вызывает остановку рекурсии после 100 рекурсий.

Тем не менее, php возвращает эту ошибку:

Неустранимая ошибка: достигнут максимальный уровень вложенности функции '100', прерывание! в D:\wamp\www\crawler1\simplehtmldom_1_5\simple_html_dom.php на линии 1355

ERROR

Я нашел решение здесь: Увеличение лимита вызовов вложенных функций но это не работает в моем случае.

Я цитирую один из ответов по ссылке, указанной выше. Пожалуйста, подумайте об этом.

«У вас установлены Zend, IonCube или xDebug? Если это так, то, вероятно, именно здесь вы и получаете эту ошибку.

Я столкнулся с этим несколько лет назад, и в итоге Zend установил этот предел, а не PHP. Конечно, его удаление позволит вам пройти 100 итераций, но в итоге вы достигнете пределов памяти ».

Есть ли способ увеличить максимальный уровень вложенности функций в PHP?

118
Rafay

Простое решение решило мою проблему. Я только что прокомментировал эту строку:

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

в моем файле php.ini. Это расширение ограничивало стек до 100, поэтому я отключил его. Рекурсивная функция теперь работает как положено.

51
Rafay

Увеличьте значение xdebug.max_nesting_level в вашем php.ini: http://xdebug.org/docs/all_settings#max_nesting_level

134
Maxence

Вместо того, чтобы использовать рекурсивные вызовы функций, работайте с моделью очереди, чтобы сгладить структуру.

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

Есть разные способы справиться с этим. Вы можете отслеживать дополнительную информацию, если вам нужно немного узнать о происхождении или пройденных путях. Существуют также распределенные очереди, которые могут работать по аналогичной модели.

43
Louis-Philippe Huberdeau

Другое решение - добавить xdebug.max_nesting_level = 200 в ваш php.ini.

40
bacar ndiaye

Вместо того, чтобы отключить xdebug, вы можете установить более высокий предел, как

xdebug.max_nesting_level = 500

23
shahinam

Это также можно исправить прямо в php, например, в файле конфигурации вашего проекта. 

ini_set('xdebug.max_nesting_level', 200);

17
svassr

Попробуйте поискать в /etc/php5/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's test до и после внесения этого изменения, чтобы увидеть, сработало ли.

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

Перейдите в файл конфигурации php.ini и измените следующую строку:

xdebug.max_nesting_level=100

что-то вроде:

xdebug.max_nesting_level=200
12
Yasssine ELALAOUI

в 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, и вам не придется беспокоиться об изменении значения уровня вложенности.

`

12
Gujarat Santana

вероятно произошло из-за xdebug.

Попробуйте прокомментировать следующую строку в вашем "php.ini" и перезапустите сервер, чтобы перезагрузить PHP.

";xdebug.max_nesting_level"

12
vandersondf

php.ini:

xdebug.max_nesting_level = -1

Я не совсем уверен, будет ли значение когда-либо переполнено и достигнет -1, но оно либо никогда не достигнет -1, либо установит max_nesting_level довольно высоким.

7
Martyn Shutt

Вы можете попытаться развернуть вложенность путем реализации параллельных рабочих (например, в кластерных вычислениях) вместо увеличения количества вызовов вложенных функций.

Например: вы определяете ограниченное количество слотов (например, 100) и отслеживаете количество «рабочих», назначенных каждому/некоторым из них. Если какие-либо слоты становятся свободными, вы помещаете ожидающих работников «в них».

6
tamasgal

Вы можете преобразовать свой рекурсивный код в итеративный код, который имитирует рекурсию. Это означает, что вам нужно поместить текущий статус (URL, документ, положение в документе и т.д.) В массив, когда вы достигнете ссылки, и вытолкнуть его из массива, когда эта ссылка будет завершена.

5
Yogu

Проверьте рекурсию из командной строки:

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

если результат> 100 ТО, проверьте лимит памяти;

4
Andrey

Если вы используете Laravel, сделайте

composer update

Это должно быть работой.

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

Постскриптум Измените 9999 на любой номер, который вы хотите.

2
cofirazak

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

0
danielad

У меня была эта проблема с WordPress на cloud9. Оказывается, это был плагин W3 Caching. Я отключил плагин, и он работал нормально.

0
sobeit

Другое решение, если вы запускаете php скрипт в 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 из браузера

0
Binod

У меня была ошибка, когда я устанавливал много плагинов. Итак, ошибка 100 показала, включая местоположение последнего плагина, который я установил C:\wamp\www\mysite\wp-content\plugins\"...", поэтому я удалил этот плагин папка на диске C: тогда все вернулось к нормальному состоянию. Я думаю, что мне нужно ограничить количество подключаемых модулей, которые я установил или активировал. Удачи, надеюсь, это поможет

0
CalvinMD