“Ölümcül hata: '100' maksimum işlev yuvalama düzeyine ulaşıldı, iptal edildi!” PHP'de


138

Bir html dosyasındaki tüm URL'leri bulan ve keşfedilen URL'lere bağlı her html içeriği için aynı işlemi tekrarlayan bir işlev yaptım. İşlev özyinelemelidir ve sonsuzca devam edebilir. Ancak, 100 özyinelemeden sonra özyinelemenin durmasına neden olan genel bir değişken ayarlayarak özyinelemeye bir sınır koydum.

Ancak, php bu hatayı döndürür:

Ölümcül hata: '100' maksimum işlev yuvalama düzeyine ulaşıldı, iptal edildi! D: \ wamp \ www \ crawler1 \ simplehtmldom_1_5 \ simple_html_dom.php 1355 satırında

HATA

Burada bir çözüm buldum: İç içe geçmiş işlev çağrı sınırını artırmak ama bu benim durumumda çalışmıyor.

Yukarıda belirtilen bağlantıdan cevaplardan birini alıntılıyorum. Lütfen düşünün.

"Zend, IonCube veya xDebug yüklü mü? Varsa, muhtemelen bu hatayı nereden alıyorsunuz demektir.

Ben birkaç yıl önce bu koştu, ve Zend PHP, orada bu sınırı koyarak sona erdi. Tabii ki kaldırmak 100 yinelemeyi geçmenize izin verecektir, ama sonunda bellek sınırlarına ulaşacaksınız. "

PHP maksimum işlev yuvalama düzeyini artırmak için bir yolu var mı


2
Ayrıca: PHP'nin iç içe işlev çağrılarında bir sınırı yoktur, buna neden olan kullandığınız bir uzantı olmalıdır.
Abel

@Abel Kodumda hata olmadığından eminim. Her özyinelemeli çağrıda değerini birer birer artıran statik bir değişken vardır. Bu değişken 100'den küçükse, özyinelemeli çağrılar değişken 100'e ulaşıncaya kadar devam eder. 100'e ulaşan değişkenin aslında temel durum olduğunu söylemek gerekir. Hata 100 yinelemeden önce ortaya çıkarken. Ve bazı uzantılarımın buna neden olduğunu belirttiğiniz gibi, simple_html_dom.php işlevlerini kullandığımı belirtmek isterim. Simple_html_dom.php hakkında herhangi bir fikriniz varsa, lütfen bu konuda bana yardımcı olun. Lütfen güncellenmiş soruya bakın.
Rafay

7
Bu xdebug bir hatadır. Ekran görüntüsünde xdebug kullandığınız görülebilir. Ayarı buradan devre dışı bırakabilirsiniz: xdebug.max_nesting_level veya yuvalama seviyesinin ne kadar büyük olduğunu söyleyebilirsiniz.
hakre

3
WAMP kullanıyorsanız, php.ini dosyasındaki xdebug işlevini devre dışı bırakmanın her zaman ÇALIŞMADIĞINI unutmayın; aynısı izin verilen yuvalama düzeyinin genişletilmesi için de geçerlidir; bir hata bir tahmin; ÇÖZÜM: php.ini adresine gidin ve php_xdebug'a yorum yapın - ???. Dll
Jeffz

Yanıtlar:


145

Değerini artırın xdebug.max_nesting_leveliçinde seninphp.ini


6
@AL Php.ini dosyanızı düzenlersiniz ve XDebug bölümüne xdebug.max_nesting_level satırını ekler veya düzenlersiniz.
Maxence

3
Ancak bu bir üretim ortamıysa, o ortamda xdebug'u devre dışı bırakmak olan kabul edilen cevaba bakın.
zkent

3
Bu, semptomu çözer (bir süre için), ancak sorunu çözmez.
Sebastian Mach

1
MAMP'ta Haxe için UFront kullanırken bu çözüm benim için çalıştı.
Sırdaş

4
sınırsız:xdebug.max_nesting_level = -1
Nabi KAZ

55

Basit bir çözüm sorunumu çözdü. Ben sadece bu satıra yorum yaptım:

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

Benim de php.inidosyaya. Bu uzantı yığını sınırlandırıyordu, 100bu yüzden devre dışı bıraktım. Özyinelemeli işlev şimdi beklendiği gibi çalışıyor.


4
Sonuçta bu XDebug uzantısıydı ... Sonuçta bilmek iyi. İki gün içinde kendi cevabınızı kabul edilen cevap olarak kabul edebilirsiniz, isterseniz (ve önceki sorularınıza bir göz atın, çoğu kabul edilen bir cevabı kaçırır).
Abel

61
Aşırı özyineleme ile başa çıkmak, sadece izlemeyi kapatmaktan daha iyidir.
petesiss

7
Bu ağır bir yaklaşım. Maksimum yığın derinliğini ayarlamak için değişkenten bahseden yukarıdaki cevaplar daha iyi bir yaklaşımdır.
aredridel

7
Bir üretim ortamında xdebug etkin değil.
HarryFink

2
kutsal saçmalık. Seçilen çözüme gülmeyi bırakamam. Böylece bilgisayarım gürültü yapmayı bırakmaz, bu yüzden çözümü buldum. Kapatmak. :)
Kevin Remisoski

44

Özyinelemeli işlev çağrıları yapmak yerine, yapıyı düzleştirmek için bir kuyruk modeliyle çalışın.

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

Bununla başa çıkmanın farklı yolları vardır. Geçilen başlangıç ​​noktası veya yollar hakkında bilgi edinmek istiyorsanız daha fazla bilgiyi takip edebilirsiniz. Benzer bir model üzerinde çalışabilecek dağıtılmış kuyruklar da vardır.


5
SPL ile kuyruğu yeniden keşfetmenize gerek yoktur: php.net/manual/tr/class.splqueue.php
Francesco

1
SPL Kuyruğu biraz daha fazla hız sağlayabilir, ancak çoğu basit görev için dizilere bağlı kalmayı seviyorum. push / pop / shift / unshift işlevlerinin tümü sağlanır.
Louis-Philippe Huberdeau

1
Bu doğru cevap. Varsayılan değerleri değiştirmekten kaçının. Kodunuzu optimize etmeye çalışın.
Junaid Atique

41

Başka bir çözüm xdebug.max_nesting_level = 200php.ini içine eklemek


8
bunu php, örneğin projenizin config dosyasında da yapmak mümkündür. ini_set('xdebug.max_nesting_level', 200);
svassr

@htxryan Uzman değilim ama bunun nedeni çağrı yığınınızın çok "derin" olması (diğer işlevleri çağıran çok fazla işlev). Bunun gerçekleştiği tipik senaryo özyinelemeli bir işlevdir. Ayar büyük olasılıkla koddaki bir hata nedeniyle "kontrol dışı" özyinelemesini önlemek içindir.
Bryan

@svassr, bu ipucunu ayrı bir cevap olarak eklemeyi veya mevcut bir cevaba eklemeyi düşünebilirsiniz, bu bana yardımcı oldu, ancak yorumlarda neredeyse kaçırdı
Bryan

@Bryan yeni bir cevap ekledi
svassr

23

Xdebug'u devre dışı bırakmak yerine, üst limiti aşağıdaki gibi ayarlayabilirsiniz:

xdebug.max_nesting_level = 500


@SebastianMach: ve şaşırtıcı bir şekilde yıllar sonra da. :) (Dört kez daha falan. İnsanlar sadece şimdi okumakla kalmıyorlar, artık kaydırma yapmıyorlar bile.)
Sz.

1
@Sz .: Vay, geçmişten ne büyük bir patlama: P Şaşırtıcı derecede şok edici.
Sebastian Mach

18

Bunu doğrudan php'de, örneğin projenizin yapılandırma dosyasında düzeltmek de mümkündür.

ini_set('xdebug.max_nesting_level', 200);


1
Teşekkürler, bu tüm dev kutuları php.ini güncelleme hakkında endişelenmenize gerek yok gibi güzel çalışır, ben sadece benim uygulama bootstrap dosyasına ekleyin.
Bryan

13

Php.ini yapılandırma dosyanıza gidin ve aşağıdaki satırı değiştirin:

xdebug.max_nesting_level=100

gibi bir şeye:

xdebug.max_nesting_level=200

13

5.59 kullanarak Ubuntu üzerinde:
`:

/etc/php5/cli/conf.d

ve xdebug.ini dosyasını bu dizinde bul, benim durumumda 20-xdebug.ini

ve bu satırı ekleyin `

xdebug.max_nesting_level = 200


veya bu

xdebug.max_nesting_level = -1

-1 olarak ayarlayın ve iç içe geçme düzeyinin değerini değiştirmek için endişelenmenize gerek yok.

'


12

muhtemelen xdebug yüzünden oldu.

"Php.ini" dosyasında aşağıdaki satırı yorumlamayı deneyin ve PHP'yi yeniden yüklemek için sunucunuzu yeniden başlatın.

  ";xdebug.max_nesting_level"


2
veya devre dışı tüm xdebug
zloctb

2
Bu nasıl olurdu? Limiti manuel olarak tanımlamazsanız, yalnızca varsayılan olan 100'e geri döner ( xdebug.org/docs/basic ). Bu satırı yorumlayarak, tüm yapmanız gereken ayarı varsayılana geri döndürmeye zorlar.
justanotherprogrammer

Aracın kullanımına bağlıysanız, tüm xdebug'u devre dışı bırakmanız önerilmez; Normalde "xdebug.max_nesting_level" yapılandırması gerçek kullanımını bilmeden kullanılır, bu nedenle genellikle yalnızca yorum yeterlidir ve geçerlidir.
vandersondf

12

Xdebug.ini adında bir dosya olup olmadığını görmek için /etc/php5/conf.d/ adresini aramayı deneyin.

max_nesting_level varsayılan olarak 100'dür

Bu dosyada ayarlanmamışsa şunu ekleyin:

xdebug.max_nesting_level=300

listenin sonuna kadar

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

daha sonra çalışıp çalışmadığını görmek için bu değişikliği yapmadan önce ve sonra @ Andrey testini kullanabilirsiniz .

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

Harika, xdebug'un ayrı bir .inidosyası olduğunu belirten ilk cevap . Bu arada php5-fpm çalıştırdığınızda bu dosya muhtemelen burada bir yerde:/etc/php5/fpm/conf.d/20-xdebug.ini
Daan

7

php.ini:

xdebug.max_nesting_level = -1

Değerin hiç taşmayacağından ve -1'e ulaşacağından emin değilim, ama ya asla -1'e ulaşmayacak, ya da max_nesting_level oldukça yüksek olacak.


İşe yarıyor! XDebug kullansanız da kullanmasanız da, php.ini satırına yorum yapmazsanız. Açıkça kullandım: ini_set ('xdebug.max_nesting_level', -1);
user2928048

6

Özyinelemeli kodunuzu özyinelemeyi simüle eden yinelemeli bir koda dönüştürebilirsiniz. Bu, bir bağlantıya ulaştığınızda geçerli durumu (url, belge, belgedeki konum vb.) Bir diziye itmeniz ve bu bağlantı tamamlandığında diziden çıkarmanız gerektiği anlamına gelir.


5

Yuvalama işlevi çağrılarının sayısını artırmak yerine paralel çalışanlar (küme bilgi işleminde olduğu gibi) uygulayarak yuvalamayı hareket ettirmeye çalışabilirsiniz.

Örneğin: sınırlı sayıda yuva (örn. 100) tanımlarsınız ve her birine / bazılarına atanan "işçi" sayısını izlersiniz. Eğer herhangi bir yuva serbest kalırsa, bekleyen çalışanları "onlara" koyarsınız.


1
Bu genel olarak uygulanabilir bir yaklaşım değildir. Bu, yığın derinliğinden kaçınmak değil, paralelleşmeye daha duyarlıdır.
aredridel

5

Komut satırından özyinelemeyi kontrol edin:

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

sonuç> 100 SONRA bellek sınırını kontrol edin;


3

Laravel kullanıyorsanız,

composer update

Bu iş olmalı.


Bununla ilgili daha fazla arka plan bilgisi eklemelisiniz. Bu laracasts.com/forum/…
ggderas

1
Bu, hatanın nedeni olabilecek xdebug / php.ini ayarlarında herhangi bir etkisi yoktur. Ayrıca bir dos döngüsünde uygulama ve sürekli bir fonksiyon etrafında döngü mümkündür, OP nerede laravel kullandıkları ve kod yudum bakarak kod devletine bakarak hiçbir yerde yaptı
James Kirkby

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

PS 9999'u istediğiniz herhangi bir sayı ile değiştirin.


1

Birçok eklenti yüklerken bir hata aldım Yani 100 hatası C: \ wamp \ www \ sitem \ wp-content \ plugins \ "..." i yüklediğim son eklentinin konumu da dahil olmak üzere gösterdi, bu yüzden bu eklentiyi sildim klasöründe C: sürücü sonra her şey normale döndü. Ben yüklemek veya etkinleştirmek plug-in miktarını sınırlamak zorunda düşünüyorum. iyi şanslar umarım yardımcı olur


1

Sizin durumunuzda, tarayıcı örneğinin, hata ve hata ayıklama bilgilerini izlemek için daha fazla Xdebug sınırına sahip olması kesinlikle.

Ancak, diğer durumlarda PHP gibi hatalar veya CodeIgniter kütüphaneleri gibi çekirdek dosyalar da böyle bir durum yaratır ve hatta x-debug seviye ayarını artırırsanız bile kaybolmaz.

Bu yüzden, kodunuza dikkatlice bakın :).

Benim durumumda sorun buydu.

CodeIgniter kitaplığı olan bir hizmet sınıfı vardı. İçinde böyle bir işlev var.

 class PaymentService {

    private $CI;

    public function __construct() {

        $this->CI =& get_instance();

   }

  public function process(){
   //lots of Ci referencing here...
   }

Benim denetleyicisi aşağıdaki gibi:

$this->load->library('PaymentService');
$this->process_(); // see I got this wrong instead  it shoud be like 

Son satırdaki işlev çağrısı yazım hatası nedeniyle yanlıştı, bunun yerine aşağıdaki gibi olmalıydı:

$this->Payment_service->process(); //the library class name

Sonra aşmak hata mesajı almaya devam ediyordu. Ama XDebug devre dışı bırakıldı ama yardım etmedi. Herhangi bir şekilde, uygun işlev çağrısı için sınıf adını veya kodunuzu kontrol edin.


Bir cevap mı yoksa bir soru mu?
AL

@daniedad Cevabınızı düzenledim, çözümü sadece kodla ilgili yorumlarda değil, metinde de yazmanın daha iyi olduğunu düşünüyorum . Ve şu anki form bana bunun yeni bir soru olduğunu, bir cevap olmadığını düşündürdü. Değişiklikleri onaylamazsanız geri dönmekten çekinmeyin.
AL

1

Cloud9'da WordPress ile bu sorunu yaşadım. W3 Caching eklentisi olduğu ortaya çıktı. Eklentiyi devre dışı bıraktım ve iyi çalıştı.


1

CLI (cmd) php betiği çalıştırıyorsanız başka bir çözüm

Bu durumda düzenleme gerektiren php.ini dosyası farklıdır. WAMP kurulumumda komut satırına yüklenen php.ini dosyası:

\wamp\bin\php\php5.5.12\php.ini

php tarayıcıdan çalıştırıldığında yüklenen \ wamp \ bin \ apache \ apache2.4.9 \ bin \ php.ini yerine


0

Yinelemeyi nesnelere sınırlamak için modifier.debug_print_var.php dosyasındaki {debug} işlevini de değiştirebilirsiniz.

45 yaşından önce, önce:

$results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
  . '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
  . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);

Sonra:

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

Bu şekilde, Xdebug hala normal davranacaktır: var_dump ve benzeri yineleme derinliğini sınırlandırın. Bu akıllıca bir sorun olduğundan, Xdebug değil!


0

Ben de aynı sorunu vardı ve ben böyle reslove:

MySQL my.ini dosyasını açın

[Mysqld] bölümünde şu satırı ekleyin: innodb_force_recovery = 1

Dosyayı kaydedin ve MySQL'i başlatmayı deneyin

Yeni eklediğiniz satırı kaldırın ve Kaydet

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.