วิธีแก้ปัญหาสำหรับ“ ข้อผิดพลาดร้ายแรง: ถึงระดับการซ้อนฟังก์ชันสูงสุดถึง 100 การยกเลิก!” ใน PHP


137

ฉันได้สร้างฟังก์ชันที่ค้นหา URL ทั้งหมดในไฟล์ html และทำซ้ำกระบวนการเดียวกันสำหรับเนื้อหา html แต่ละรายการที่เชื่อมโยงกับ URL ที่ค้นพบ ฟังก์ชั่นนี้เกิดซ้ำและสามารถทำงานต่อไปได้ไม่รู้จบ อย่างไรก็ตามฉันได้ จำกัด การเรียกซ้ำโดยตั้งค่าตัวแปรส่วนกลางซึ่งทำให้การเรียกซ้ำหยุดหลังจากเรียกซ้ำ 100 ครั้ง

อย่างไรก็ตาม php ส่งคืนข้อผิดพลาดนี้:

ข้อผิดพลาดร้ายแรง: ฟังก์ชันการซ้อนสูงสุดถึง '100' ถึงยกเลิกแล้ว! ใน D: \ wamp \ www \ crawler1 \ simplehtmldom_1_5 \ simple_html_dom.php ที่บรรทัด 1355

ข้อผิดพลาด

ฉันพบวิธีแก้ปัญหาที่นี่: การเพิ่มขีด จำกัด การเรียกฟังก์ชันซ้อนแต่นี่ไม่ได้ผลในกรณีของฉัน

ฉันอ้างอิงหนึ่งในคำตอบจากลิงค์ที่กล่าวถึงข้างต้น โปรดพิจารณาด้วย

"คุณมี Zend, IonCube หรือ xDebug ติดตั้งอยู่หรือไม่ถ้าใช่นั่นอาจเป็นที่ที่คุณได้รับข้อผิดพลาดนี้

ฉันวิ่งเข้าไปในนี้ไม่กี่ปีที่ผ่านมาและในที่สุดก็กลายเป็น Zend วางข้อ จำกัด ที่นั่นไม่ใช่ PHP แน่นอนว่าการลบมันจะช่วยให้คุณผ่านการทำซ้ำได้ 100 ครั้ง แต่ในที่สุดคุณจะถึงขีด จำกัด หน่วยความจำ "

มีวิธีเพิ่มระดับการซ้อนฟังก์ชันสูงสุดใน PHP หรือไม่


2
นอกจากนี้: PHP ไม่ได้มีข้อ จำกัด ในการเรียกใช้ฟังก์ชันที่ซ้อนกันมันจะต้องเป็นส่วนขยายที่คุณใช้ซึ่งเป็นสาเหตุให้เกิดสิ่งนี้
Abel

@Abel ฉันแน่ใจว่ารหัสของฉันไม่มีข้อผิดพลาด มีตัวแปรแบบสแตติกซึ่งจะเพิ่มค่าของมันทีละหนึ่งในการโทรซ้ำแต่ละครั้ง หากตัวแปรนั้นน้อยกว่า 100 การเรียกแบบเรียกซ้ำจะดำเนินต่อไปจนกว่าตัวแปรจะถึง 100 ผมหมายถึงว่าตัวแปรถึง 100 นั้นเป็นกรณีพื้นฐาน ในขณะที่ข้อผิดพลาดเกิดขึ้นก่อนการเรียกซ้ำ 100 ครั้ง และอย่างที่คุณได้กล่าวไปแล้วว่าส่วนขยายของฉันเป็นสาเหตุของเรื่องนี้ฉันอยากจะพูดถึงว่าฉันกำลังใช้ฟังก์ชั่นจาก simple_html_dom.php หากคุณมีความคิดเกี่ยวกับ simple_html_dom.php โปรดช่วยฉันในเรื่องนี้ โปรดอ้างอิงคำถามที่ปรับปรุง
Rafay

7
นั่นเป็นข้อผิดพลาดโดย xdebug จากภาพหน้าจอจะมองเห็นคุณใช้ xdebug คุณสามารถปิดการตั้งค่าได้ที่นี่: xdebug.max_nesting_levelหรือบอกระดับการซ้อน
hakre

3
หากใช้ WAMP โปรดทราบว่าการปิดใช้งาน xdebug ใน php.ini นั้นไม่ได้ผลเสมอไป เช่นเดียวกับการขยายระดับของการซ้อนที่อนุญาต ข้อผิดพลาดเดา การแก้ไข: ไปที่ php.ini และแสดงความคิดเห็น php_xdebug - ???. dll
Jeffz

คำตอบ:


145

เพิ่มมูลค่าของxdebug.max_nesting_levelในของคุณphp.ini


6
@AL คุณแก้ไขไฟล์ php.ini ของคุณและเพิ่มหรือแก้ไขบรรทัด xdebug.max_nesting_level ในส่วน XDebug
Maxence

3
อย่างไรก็ตามหากนี่คือสภาพแวดล้อมการใช้งานจริงให้ดูคำตอบที่ยอมรับซึ่งคือการปิดการใช้งาน xdebug ในสภาพแวดล้อมนั้น
zkent

3
วิธีนี้จะช่วยแก้อาการ (ชั่วขณะหนึ่ง) แต่ไม่ใช่ปัญหา
เซบาสเตียนมัค

1
วิธีนี้ใช้ได้ผลกับฉันเมื่อฉันใช้ UFront สำหรับ Haxe กับ MAMP
สนิท

4
สำหรับไม่ จำกัด :xdebug.max_nesting_level = -1
Nabi KAZ

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 หลังจากทั้งหมด ... ดีที่จะรู้ ในสองวันคุณสามารถยอมรับคำตอบของคุณเองเป็นคำตอบที่ยอมรับได้ถ้าคุณต้องการ (และดูคำถามก่อนหน้านี้ของคุณส่วนใหญ่จะพลาดคำตอบที่ยอมรับ)
Abel

61
การจัดการกับการสอบถามซ้ำที่มากเกินไปย่อมดีกว่าการปิดการตรวจสอบ
petesiss

7
นั่นเป็นวิธีที่หนักหน่วง คำตอบข้างต้นที่กล่าวถึงตัวแปรในการปรับความลึกสูงสุดของสแต็กเป็นวิธีที่ดีกว่า
aredridel

7
คุณไม่ได้เปิดใช้ xdebug ในสภาพแวดล้อมการผลิต
HarryFink

2
อึศักดิ์สิทธิ์ ฉันหยุดหัวเราะไม่ได้กับวิธีแก้ปัญหาที่เลือก ดังนั้นพีซีของฉันจะไม่หยุดส่งเสียงรบกวนดังนั้นฉันจึงพบวิธีแก้ปัญหา ปิดมัน. :)
Kevin Remisoski

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
ด้วย SPL คุณไม่จำเป็นต้องบูรณาการคิว: php.net/manual/en/class.splqueue.php
Francesco

1
SPL Queue อาจให้ความเร็วเพิ่มขึ้นอีกเล็กน้อย แต่ฉันชอบที่จะติดตั้งอาร์เรย์สำหรับงานที่ง่ายที่สุด มีการจัดเตรียม push / pop / shift / unshift
หลุยส์ฟิลิปป์ Huberdeau

1
นี่คือคำตอบที่ถูกต้อง หลีกเลี่ยงการเปลี่ยนแปลงค่าเริ่มต้น พยายามเพิ่มประสิทธิภาพรหัสของคุณ
Junaid Atique

41

อีกวิธีคือการเพิ่มxdebug.max_nesting_level = 200php.ini ของคุณ


8
นอกจากนี้ยังเป็นไปได้ที่จะทำใน php เช่นในไฟล์กำหนดค่าของโครงการของคุณ ini_set('xdebug.max_nesting_level', 200);
svassr

@ htxryan ฉันไม่ใช่ผู้เชี่ยวชาญ แต่เป็นเพราะ call stack ของคุณนั้น "ลึก" เกินไป (มีฟังก์ชั่นมากเกินไปที่เรียกใช้ฟังก์ชันอื่น ๆ ) สถานการณ์ทั่วไปที่สิ่งนี้เกิดขึ้นกับฟังก์ชั่นวนซ้ำ การตั้งค่ามีแนวโน้มที่จะหลีกเลี่ยงการเรียกซ้ำ "เกินการควบคุม" เนื่องจากข้อบกพร่องในรหัส
ไบรอัน

@svassr คุณอาจต้องการพิจารณาเพิ่มเคล็ดลับนั้นเป็นคำตอบแยกต่างหากหรือเพิ่มไปยังคำแนะนำที่มีอยู่มันเป็นประโยชน์กับฉัน แต่เกือบจะพลาดมันในความคิดเห็น
Bryan

@Bryan เพิ่งเพิ่มคำตอบ
svassr

23

แทนที่จะปิดการใช้งาน xdebug คุณสามารถตั้งค่าขีด จำกัด ที่สูงกว่าเช่น

xdebug.max_nesting_level = 500


@SebastianMach: และปีต่อ ๆ ไปด้วยเช่นกัน :) (เหมือนอีกสี่ครั้งหรือมากกว่านั้นผู้คนไม่เพียง แต่ไม่ได้อ่านในตอนนี้พวกเขาไม่ได้เลื่อนอีกต่อไป)
Sz

1
@ Sz: ว้าวสิ่งที่น่าประทับใจในอดีต: P ตกตะลึงอย่างน่าอัศจรรย์
เซบาสเตียนมัค

18

นอกจากนี้ยังเป็นไปได้ที่จะแก้ไขได้โดยตรงใน php ตัวอย่างเช่นในไฟล์กำหนดค่าของโครงการของคุณ

ini_set('xdebug.max_nesting_level', 200);


1
ขอบคุณสิ่งนี้ใช้ได้ดีเพราะฉันไม่ต้องกังวลกับการอัปเดต php.ini ในกล่อง dev ทั้งหมดของฉันฉันเพิ่งเพิ่มมันลงในไฟล์ bootstrap ของแอปพลิเคชันของฉัน
ไบรอัน

13

ไปที่ไฟล์กำหนดค่า php.ini ของคุณและเปลี่ยนบรรทัดต่อไปนี้:

xdebug.max_nesting_level=100

เพื่อสิ่งที่ชอบ:

xdebug.max_nesting_level=200

13

บน Ubuntu ที่ใช้ PHP 5.59:
ไปที่ `:

/etc/php5/cli/conf.d

และค้นหาxdebug.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" จะถูกใช้โดยไม่ทราบว่าการใช้งานจริงของเขาดังนั้นโดยทั่วไปจะมีเพียงความคิดเห็นที่เพียงพอและถูกต้อง
vandersondf

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

จากนั้นคุณสามารถใช้การทดสอบของ @ Andreyก่อนและหลังการเปลี่ยนแปลงนี้เพื่อดูว่าทำงานหรือไม่

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

หากคุณใช้ Laravel ให้ทำ

composer update

มันควรจะใช้ได้


คุณควรเพิ่มข้อมูลพื้นหลังเพิ่มเติมเกี่ยวกับสิ่งนี้ สิ่งนี้อาจมีประโยชน์แม้ว่าlaracasts.com/forum/…
ggderas

1
สิ่งนี้ไม่มีผลต่อการตั้งค่า xdebug / php.ini ซึ่งอาจเป็นสาเหตุของข้อผิดพลาด นอกจากนี้ยังเป็นไปได้ว่าแอปพลิเคชันของคุณอยู่ในโหมดวนรอบและวนรอบฟังก์ชันอย่างต่อเนื่องไม่มีสถานะ OP ใดที่พวกเขาใช้ laravel และดูที่รหัสของเขาจิบมันน่าจะเป็น codeigniter
James Kirkby

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

PS เปลี่ยน 9999 เป็นหมายเลขที่คุณต้องการ


1

ฉันมีข้อผิดพลาดเมื่อฉันติดตั้งปลั๊กอินจำนวนมากดังนั้นข้อผิดพลาด 100 ที่แสดงรวมถึงตำแหน่งของปลั๊กอินล่าสุดที่ฉันติดตั้ง C: \ wamp \ www \ mysite \ wp-content \ plugins \ "... " ดังนั้นฉันจึงลบปลั๊กอินนี้ โฟลเดอร์บนไดรฟ์ C: แล้วทุกอย่างก็กลับมาเป็นปกติฉันคิดว่าฉันต้อง จำกัด จำนวนปลั๊กอินที่ติดตั้งหรือเปิดใช้งานโชคดีฉันหวังว่ามันจะช่วยได้


1

ในกรณีของคุณแน่นอนว่าอินสแตนซ์ของโปรแกรมรวบรวมข้อมูลมีขีด จำกัด 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 แต่ไม่ช่วย วิธีใด ๆ โปรดตรวจสอบชื่อคลาสหรือรหัสของคุณสำหรับการเรียกฟังก์ชันที่เหมาะสม


มันเป็นคำตอบหรือคำถาม?
อัล

@daniedad ฉันได้แก้ไขคำตอบของคุณแล้วฉันคิดว่ามันดีกว่าที่จะเขียนคำตอบในข้อความและไม่เพียง แต่ในความคิดเห็นที่แนบมากับรหัส และรูปแบบปัจจุบันทำให้ฉันคิดว่ามันเป็นคำถามใหม่และไม่ใช่คำตอบ คุณสามารถย้อนกลับได้หากคุณไม่อนุมัติการเปลี่ยนแปลง
อัล

1

ฉันมีปัญหานี้กับ WordPress บน cloud9 ปรากฎว่าเป็นปลั๊กอินสำหรับแคช W3 ฉันปิดการใช้งานปลั๊กอินและทำงานได้ดี


1

โซลูชันอื่นหากคุณใช้งานสคริปต์ 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

คุณยังสามารถแก้ไขฟังก์ชัน {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!


0

ฉันมีปัญหาเดียวกันและฉัน reslove เช่นนี้

เปิดไฟล์ MySQL my.ini

ในส่วน [mysqld] ให้เพิ่มบรรทัดต่อไปนี้: innodb_force_recovery = 1

บันทึกไฟล์และลองเริ่ม MySQL

ลบบรรทัดที่คุณเพิ่งเพิ่มและบันทึก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.