"घातक त्रुटि के लिए समाधान: '100' के अधिकतम फ़ंक्शन नेस्टिंग स्तर पर पहुंच गया, गर्भपात!" PHP में


137

मैंने एक फ़ंक्शन बनाया है जो एक HTML फ़ाइल के भीतर सभी URL पाता है और खोजे गए URL से जुड़ी प्रत्येक HTML सामग्री के लिए एक ही प्रक्रिया को दोहराता है। फ़ंक्शन पुनरावर्ती है और अंतहीन पर जा सकता है। हालाँकि, मैंने ग्लोबल वैरिएबल सेट करके रिकर्सन पर एक लिमिट लगा दी है, जिससे रिकर्सन 100 रिक्रिएशन के बाद बंद हो जाता है।

हालाँकि, php इस त्रुटि को लौटाता है:

घातक त्रुटि: '100' के अधिकतम फ़ंक्शन नेस्टिंग स्तर पर पहुंच गया, गर्भपात! डी में: \ wamp \ www \ क्रॉलर 1 \ simplehtmldom_1_5 \ simple_html_dom.php पंक्ति 1355 पर

त्रुटि

मुझे यहां एक समाधान मिला: नेस्टिंग फंक्शन कॉल की सीमा बढ़ रही है लेकिन यह मेरे मामले में काम नहीं कर रहा है।

मैं ऊपर दिए गए लिंक में से एक उत्तर को उद्धृत कर रहा हूं। कृपया इस पर विचार करें।

"क्या आपके पास Zend, IonCube, या xDebug स्थापित है? यदि हां, तो शायद यही वह जगह है जहाँ से आपको यह त्रुटि मिल रही है।

मैं कुछ साल पहले इस में भाग गया, और यह समाप्त हो गया Zend कि सीमा नहीं है, वहाँ PHP नहीं है। निश्चित रूप से इसे हटाने से आप 100 पुनरावृत्तियों से आगे निकल जाएंगे, लेकिन आप अंततः मेमोरी सीमा पर पहुंच जाएंगे। "

क्या PHP में अधिकतम फ़ंक्शन नेस्टिंग स्तर को बढ़ाने का एक तरीका है


2
इसके अलावा: PHP के पास नेस्टेड फ़ंक्शन कॉल की सीमा नहीं है, यह एक ऐसा एक्सटेंशन होना चाहिए जिसका आप उपयोग कर रहे हैं।
हाबिल २

@ मुझे विश्वास है कि मेरे कोड में कोई त्रुटि नहीं है। एक स्थिर चर है जो प्रत्येक पुनरावर्ती कॉल पर एक-एक करके इसके मूल्य में वृद्धि करता है। यदि वह चर 100 से कम है, तो पुनरावर्ती कॉल 100 चर तक पहुंचने तक चलते हैं। मेरा कहने का मतलब है कि चर 100 तक पहुंचना वास्तव में आधार मामला है। जबकि त्रुटि 100 पुनरावृत्तियों से पहले उत्पन्न होती है। और जैसा कि आपने उल्लेख किया है कि कुछ एक्सटेंशन मेरे कारण बन रहे हैं, मैं यह उल्लेख करना चाहूंगा कि मैं simple_html_dom.php से फ़ंक्शन का उपयोग कर रहा हूं। यदि आपके पास simple_html_dom.php के बारे में कोई विचार है, तो कृपया इस संबंध में मेरी मदद करें। कृपया अद्यतन प्रश्न का संदर्भ लें।
राफे

7
यह xdebug द्वारा एक त्रुटि है। स्क्रीनशॉट से यह दिखाई देता है कि आप xdebug का उपयोग करते हैं। आप यहां सेटिंग को अक्षम कर सकते हैं: xdebug.max_nesting_level या बताएं कि घोंसले का स्तर कितना बड़ा है।
हकरे

3
यदि WAMP का उपयोग करते हैं, तो ध्यान दें कि xpebug को php.ini में अक्षम करना हमेशा काम नहीं करता है; अनुमत घोंसले के शिकार के स्तर पर समान लागू होता है; एक बग एक अनुमान; समाधान: php.ini पर जाएं और php_xdebug - ??? dll
Jeffz

जवाबों:


145

xdebug.max_nesting_levelअपने में मूल्य बढ़ाएँphp.ini


6
@AL आप अपनी php.ini फ़ाइल को संपादित करते हैं और आप XDebug सेक्शन में लाइन xdebug.max_nesting_level जोड़ते हैं या संपादित करते हैं।
मैक्सेंस

3
हालाँकि अगर यह एक उत्पादन वातावरण है, तो स्वीकृत उत्तर देखें, जो कि उस वातावरण में xdebug को अक्षम करना है।
zkent

3
यह लक्षण को हल करता है (थोड़ी देर के लिए), लेकिन समस्या नहीं।
सेबेस्टियन मच

1
इस समाधान ने मेरे लिए तब काम किया जब मैं हेमेक्स के लिए UFront का उपयोग MAMP पर कर रहा था।
विश्वासपात्र

4
असीमित के लिए:xdebug.max_nesting_level = -1
नबी काज

55

एक सरल उपाय से मेरी समस्या हल हो गई। मैंने इस लाइन पर टिप्पणी की:

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

मेरी php.iniफाइल में। यह एक्सटेंशन स्टैक को सीमित कर 100रहा था इसलिए मैंने इसे अक्षम कर दिया। पुनरावर्ती फ़ंक्शन अब प्रत्याशित के रूप में काम कर रहा है।


4
तो, आखिरकार यह XDebug विस्तार था आखिर ... अच्छा पता है। दो दिनों में आप अपने स्वयं के उत्तर को स्वीकार किए गए उत्तर के रूप में स्वीकार कर सकते हैं, यदि आप चाहते हैं (और आपके पिछले प्रश्नों पर एक नज़र है, तो अधिकांश स्वीकृत उत्तर को याद करते हैं)।
हाबिल

61
अत्यधिक निगरानी से निपटना निश्चित रूप से निगरानी बंद करने से बेहतर है।
पेटिस

7
यह एक भारी-भरकम दृष्टिकोण है। उपरोक्त उत्तर जो अधिकतम स्टैक गहराई को समायोजित करने के लिए चर का उल्लेख करते हैं, एक बेहतर दृष्टिकोण है।
aredridel

7
आपने बताया कि उत्पादन वातावरण में xdebug सक्षम नहीं है।
हैरीफिंक

2
बकवास। मैं चुने हुए समाधान पर हँसना बंद नहीं कर सकता। इसलिए मेरा पीसी शोर करना बंद नहीं करेगा, इसलिए मैंने इसका हल ढूंढ लिया। इसे बंद करें। :)
केविन रिमिसोस्की

44

पुनरावर्ती फ़ंक्शन कॉल के लिए जाने के बजाय, संरचना को समतल करने के लिए एक कतार मॉडल के साथ काम करें।

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

इसे संभालने के अलग-अलग तरीके हैं। यदि आपको मूल या पथ के बारे में कुछ जानकारी चाहिए तो आप अधिक जानकारी का ट्रैक रख सकते हैं। वहाँ भी वितरित कतारों कि एक समान मॉडल से काम कर सकते हैं।


5
एसपीएल के साथ आपको कतार को मजबूत
फ्रांसेस्को

1
एसपीएल कतार थोड़ा और गति प्रदान कर सकती है, लेकिन मुझे सबसे सरल कार्यों के लिए सरणियों से चिपके रहना पसंद है। पुश / पॉप / शिफ्ट / अनशिफ्ट सभी प्रदान किए जाते हैं।
लुइस-फिलिप ह्यूबरडे 15

1
यह सही जवाब है। डिफ़ॉल्ट मानों को बदलने से बचें। अपने कोड को अनुकूलित करने का प्रयास करें।
जुनैद अतीक

41

एक और उपाय xdebug.max_nesting_level = 200अपने php.ini में जोड़ना है


8
यह आपके php में भी संभव है, उदाहरण के लिए आपके प्रोजेक्ट की config फाइल में। ini_set('xdebug.max_nesting_level', 200);
svassr

@htxryan मैं एक विशेषज्ञ नहीं हूं, लेकिन यह आपके कॉल स्टैक के बहुत अधिक "गहरा" होने के कारण है (अन्य कार्यों को कॉल करने वाले बहुत सारे कार्य)। ऐसा होने वाला विशिष्ट परिदृश्य एक पुनरावर्ती फ़ंक्शन के साथ है। कोड में बग के कारण "नियंत्रण से बाहर" पुनरावृत्ति से बचने के लिए सेटिंग की सबसे अधिक संभावना है।
ब्रायन

@svassr आप एक अलग जवाब के रूप में उस टिप को जोड़ने या किसी मौजूदा को जोड़ने पर विचार करना चाह सकते हैं, यह मेरे लिए उपयोगी था, लेकिन टिप्पणियों में लगभग इसे याद किया
ब्रायन

@ ब्रायन ने सिर्फ एक जवाब जोड़ा
svassr

23

Xdebug को अक्षम करने के बजाय, आप उच्च सीमा जैसे सेट कर सकते हैं

xdebug.max_nesting_level = 500


@SebastianMach: और, आश्चर्यजनक रूप से, वर्षों बाद भी। :) (जैसे चार बार या उससे अधिक। लोग न केवल अब पढ़ते हैं, वे भी अधिक स्क्रॉल नहीं करते हैं।)
Sz

1
@Sz: वाह, क्या अतीत से एक विस्फोट है: पी आश्चर्यजनक रूप से चौंकाने वाला।
सेबेस्टियन मच

18

इसे सीधे php में ठीक करना भी संभव है, उदाहरण के लिए आपके प्रोजेक्ट की कॉन्फ़िग फ़ाइल में।

ini_set('xdebug.max_nesting_level', 200);


1
धन्यवाद, यह अच्छी तरह से काम करता है क्योंकि मुझे अपने सभी देव बॉक्स पर php.ini को अपडेट करने के बारे में चिंता करने की ज़रूरत नहीं है, मैं इसे केवल अपने एप्लिकेशन के बूटस्ट्रैप फ़ाइल में जोड़ता हूं।
ब्रायन

13

अपनी php.ini कॉन्फ़िगरेशन फ़ाइल में जाएं और निम्न पंक्ति बदलें:

xdebug.max_nesting_level=100

कुछ इस तरह से:

xdebug.max_nesting_level=200

13

PHP 5.59 का उपयोग करके Ubuntu पर:
`के लिए मिला:

/etc/php5/cli/conf.d

और अपने ddebug.ini को उस dir में पाएं , मेरे मामले में 20-xdebug.ini है

और इस लाइन को जोड़ दें `

xdebug.max_nesting_level = 200


या यह

xdebug.max_nesting_level = -1

इसे -1 पर सेट करें और आपको नेस्टिंग स्तर के मूल्य को बदलने की चिंता नहीं करनी चाहिए।

`


12

शायद xdebug के कारण हुआ।

अपने "php.ini" में निम्न लाइन पर टिप्पणी करने का प्रयास करें और PHP को पुनः लोड करने के लिए अपने सर्वर को पुनरारंभ करें।

  ";xdebug.max_nesting_level"


2
या अक्षम सभी xdebug
zloctb

2
यह कैसे काम करेगा? यदि आप मैन्युअल रूप से सीमा को परिभाषित नहीं करते हैं, तो यह केवल डिफ़ॉल्ट पर वापस आ जाएगा, जो कि 100 ( xdebug.org/docs/basic ) है। इस पंक्ति को बाहर टिप्पणी करके, आप इसे डिफ़ॉल्ट पर वापस करने के लिए सेटिंग को बाध्य करते हैं।
justanotherprogrammer

यदि आप उपकरण के उपयोग पर निर्भर करते हैं तो सभी xdebug को अक्षम करने की अनुशंसा नहीं की जाती है; आम तौर पर कॉन्फ़िगरेशन "xdebug.max_nesting_level" का उपयोग उसके वास्तविक उपयोग को जाने बिना किया जाता है, इसलिए आमतौर पर केवल टिप्पणी ही पर्याप्त और मान्य होती है।
वंडरसॉन्फ़

12

/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

फिर आप यह देखने के लिए कि यह काम करने से पहले और बाद में @ एंड्रे के परीक्षण का उपयोग कर सकते हैं।

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

महान, पहला उत्तर जो बताता है कि xdebug की एक अलग .iniफ़ाइल है। वैसे जब आप php5-fpm चलाते हैं तो यह फाइल शायद यहीं है:/etc/php5/fpm/conf.d/20-xdebug.ini
Daan

7

php.ini:

xdebug.max_nesting_level = -1

मुझे पूरी तरह से यकीन नहीं है कि क्या मूल्य कभी अतिप्रवाह होगा और -1 तक पहुंच जाएगा, लेकिन यह या तो कभी भी -1 तक नहीं पहुंच पाएगा, या यह max_nesting_level को बहुत अधिक सेट करेगा।


यह काम करता हैं! कोई फर्क नहीं पड़ता कि आप XDebug का उपयोग करते हैं या नहीं, और न ही यदि आप php.ini में लाइन की टिप्पणी करते हैं। मैंने स्पष्ट रूप से उपयोग किया: ini_set ('xdebug.max_nesting_level', -1);
user2928048

6

आप अपने पुनरावर्ती कोड को पुनरावृति कोड में परिवर्तित कर सकते हैं, जो पुनरावृत्ति का अनुकरण करता है। इसका मतलब है कि आपको किसी लिंक पर पहुंचने पर वर्तमान स्थिति (url, दस्तावेज़, दस्तावेज़ में स्थिति आदि) को धकेलना होगा, और जब यह लिंक समाप्त हो जाएगा, तो इसे सरणी से बाहर निकाल देंगे।


5

आप नेस्टिंग फ़ंक्शन कॉल की संख्या बढ़ाने के बजाय समानांतर श्रमिकों (जैसे क्लस्टर कंप्यूटिंग) को लागू करके नेस्टिंग को नीचे गिराने का प्रयास कर सकते हैं।

उदाहरण के लिए: आप सीमित संख्या में स्लॉट्स (उदाहरण। 100) को परिभाषित करते हैं और उनमें से प्रत्येक को सौंपे गए "श्रमिकों" की संख्या की निगरानी करते हैं। यदि कोई स्लॉट मुक्त हो जाता है, तो आप प्रतीक्षा श्रमिकों को "उनमें" डालते हैं।


1
यह वास्तव में लागू दृष्टिकोण नहीं है। यह अधिक समझदार है कि समानांतर रखें, ढेर की गहराई से बचें।
aredridel

5

कमांड लाइन से पुनरावृत्ति जांचें:

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

यदि परिणाम> 100 मेमोरी जाँच की सीमा;


3

यदि आप लारवेल का उपयोग कर रहे हैं, तो करें

composer update

यह काम होना चाहिए।


आपको इसके बारे में अधिक पृष्ठभूमि जानकारी जोड़नी चाहिए। यह उपयोगी हो सकता है, हालांकि laracasts.com/forum/…
ggderas

1
इसका xdebug / php.ini सेटिंग्स पर कोई असर नहीं है जो त्रुटि का कारण हो सकता है। यह भी संभव है कि आप आवेदन एक डॉस लूप में हैं और एक फ़ंक्शन के आसपास लगातार लूपिंग कर रहे हैं, कोई ओपी राज्य नहीं था जहां वे लार्वा का उपयोग कर रहे थे और उनके कोड को देखकर कोडिनेटर होने की संभावना को देखते हुए
जेम्स किर्बी

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

पुनश्च 9999 को अपने इच्छित नंबर पर बदलें।


1

जब मैं कई प्लगइन्स स्थापित कर रहा था तो मुझे एक त्रुटि हुई थी इसलिए त्रुटि 100 में अंतिम प्लगइन का स्थान भी शामिल था जिसे मैंने C: \ wamp \ www \ mysite \ wp-content \ plugins \ "..." स्थापित किया था। C: ड्राइव पर फ़ोल्डर तब सब कुछ वापस सामान्य हो गया था। मुझे लगता है कि मुझे प्लग-इन स्थापित करने या सक्रिय करने की मात्रा को सीमित करना होगा। अच्छी किस्मत मुझे आशा है कि यह मदद करता है।


1

आपके मामले में यह निश्चित रूप से क्रॉलर उदाहरण त्रुटि और डीबग जानकारी का पता लगाने के लिए अधिक Xdebug सीमा है।

लेकिन, अन्य मामलों में भी PHP या कोर फ़ाइलों की तरह त्रुटियां जैसे 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 को अक्षम कर दिया, लेकिन गैर मदद की। किसी भी तरह से आप उचित फ़ंक्शन कॉलिंग के लिए वर्ग नाम या अपने कोड की जाँच करें।


यह एक जवाब है या एक सवाल है?
अल

@daniedad मैंने आपका उत्तर संपादित किया, मुझे लगता है कि इसका समाधान पाठ में लिखना बेहतर है और न केवल कोड से जुड़ी टिप्पणियों में। और वर्तमान रूप ने मुझे यह सोचने पर मजबूर कर दिया कि यह एक नया प्रश्न था और उत्तर नहीं। यदि आप परिवर्तनों को अस्वीकार कर देते हैं तो रोलबैक के लिए स्वतंत्र महसूस करें।
AL

1

मुझे क्लाउड 9 पर वर्डप्रेस के साथ यह मुद्दा मिला था। यह W3 कैशिंग प्लगइन था। मैंने प्लगइन को निष्क्रिय कर दिया और यह ठीक काम कर गया।


1

एक और उपाय यदि आप CLI में php स्क्रिप्ट चला रहे हैं (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

आप ऑब्जेक्ट में इसकी पुनरावृत्ति को सीमित करने के लिए modifier.debug_print_var.php में {debug} फ़ंक्शन को भी संशोधित कर सकते हैं।

लगभग 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 नहीं!


0

मैं एक ही समस्या थी और मैं इस तरह से हल करता हूं:

MySQL my.ini फाइल खोलें

[Mysqld] अनुभाग में, निम्न पंक्ति जोड़ें: innodb_force_recovery = 1

फ़ाइल सहेजें और MySQL शुरू करने का प्रयास करें

उस लाइन को हटा दें जिसे आपने अभी जोड़ा है और सेव करें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.