2013-08-21 14 views
5

Bu beni delirtiyor. Özyinelemeli fonksiyonlar 5.4.4 ve 5.1.6'da (kontrolüm olmayan bir müşterinin barındırma sunucusu) farklı çalışır. Gerçekten örnek dışında bunu açıklayamam:PHP özyinelemeli fonksiyonlar farklı versiyonlarda farklı mı çalışıyor?

PHP On
<?php 
$simpsons[0] = array("name"=>"Abe","parent"=>-1); 
$simpsons[1] = array("name"=>"Homer","parent"=>0); // Homer's parent is Abe 
$simpsons[2] = array("name"=>"Bart","parent"=>1); // Bart's parent is Homer 
$simpsons[3] = array("name"=>"Lisa","parent"=>1); // Lisa's parent is Homer 
$simpsons[4] = array("name"=>"Maggie","parent"=>1); // Maggie's parent is Homer 


function get_children($parent) { 
    global $simpsons; 

    foreach ($simpsons as $index=>$onesimpson) { 
     if ($onesimpson["parent"]==$parent) { 
      echo "$onesimpson[name] is a child of ".$simpsons[$parent]["name"].".<br />\n"; 
      get_children($index); 
     } 
    } 
} 

get_children(0); 
?> 

çıktı PHP üzerinde

Homer is a child of Abe. 
Bart is a child of Homer. 
Lisa is a child of Homer. 
Maggie is a child of Homer. 

ederken çıkış

Homer is a child of Abe. 
Bart is a child of Homer. 

I 5.1.6 olduğunu 5.4.4 Terminolojiyle pek iyi değilim, bu yüzden neler olduğunu açıklayamıyorum (5.1.6'daki çağrılan işlev çağrılan işlev bittiğinde bile çağrılan işlevin parametresini değiştirir), ancak bunu PHP sanal alanında çevrimiçi olarak test ettim. bu iki versi sorunlar ve sorun aynı - kurulum veya barındırma sunucusu kurulumuna özgü değil.

+1

Sorun onaylandı: http://3v4l.org/n1mVc –

+1

$ simpsons'ı, benim için ilk kırmızı bayrak olan bir dizi olarak asla tanımlamazsınız. Eğer '$ simpsons = array() 'i eklerseniz' 'hemen sonra <

+0

@ AndrewG.Johnson: Beni bu kadar üzdüğü kadar geçerli PHP kodu. $ simpsons [0] = dizi ("name" => "Abe", "parent" => - 1); 'bir dizi otomatik olarak oluşturacaktır. Dokümanlar: http://www.php.net/manual/en/language.types.array.php#language.types.array.syntax.modifying Bu son derece cesaret kırıcı fakat geçerli. –

cevap

3

Kodunuzu biraz değiştirdim. Görünüşte, $simpsons dizi referansını özyinelemenize bir parametre olarak ilettiğinizde, tüm sürümlerde çalışır.

$simpsons = array(); 
$simpsons[0] = array("name"=>"Abe","parent"=>-1); 
$simpsons[1] = array("name"=>"Homer","parent"=>0); // Homer's parent is Abe 
$simpsons[2] = array("name"=>"Bart","parent"=>1); // Bart's parent is Homer 
$simpsons[3] = array("name"=>"Lisa","parent"=>1); // Lisa's parent is Homer 
$simpsons[4] = array("name"=>"Maggie","parent"=>1); // Maggie's parent is Homer 


function get_children($simpsons, $parent) { 
    foreach ($simpsons as $index=>$onesimpson) { 
    if ($onesimpson["parent"]==$parent) { 
     echo "$onesimpson[name] is a child of ".$simpsons[$parent]["name"].".<br />\n"; 
     get_children($simpsons, $index); 
    } 
    } 
} 

get_children($simpsons, 0); 
+0

Test edildi, bu işe yarıyor! http://3v4l.org/aSr6C :-D –

+0

Bu açıkça bir cevaptır, ama merak ediyorum 'küresel $ simpsons; 'hatalara neden oldu. Belki geçmişte düzeltilmiş bir hataydı. –

+1

Teşekkürler, onu orijinal soruna (bir çevrimiçi mağazadaki ürün kategorilerini toplayarak) uygulamayı başardım ve büyük olasılıkla işe yaradı, büyük olasılıkla, küresel varsayı sola ve sağa bildirmek yerine bunu doğru şekilde yapmanın en iyi yolu – L84

8

O 5.2'de çalışmaya başlamak yapmak için değiştirildi emin değilim, ama bir dizi tek iç işaretçi (yani foreach tarafından kullanılan budur) vardır, böylece böyle bir global dizi kullandığınızda Sonuç olarak 5.2'ye kadar çıkan versiyonlarda çok anlam ifade ediyor. Bir foreach döngüsünü başlatırsanız, iç işaretçi ilerler, sonra rec_ively get_children'i çağırır, başka bir foreach döngüsünü başlatır ve iç işaretçi sıfırlar ve sonra dizi boyunca yineleme yapar.

Arayana geri döndüğünüzde, iç işaretçi dizinin sonunda olacak ve foreach döngüsü tamamlanacak. To quote the manual:

Foreach, iç dizi işaretçisine bağlı olduğu için, döngü içinde değişmesi beklenmedik davranışlara yol açabilir.

Foreach içinde foreach kullanarak aynı dizide bunun bir örneği verilmiştir.

foreach bir çalışır çıkıyor:

Düzenleme Ben sürümü 5.2.1 sabit işaretlenmiş edildi alakalı hata raporları birkaç bulundu dizinin klonu, böylece yuvalama foreach döngüleri mükemmel bir şekilde geçerlidir ve bu aslında, 5.2.1'e kadar foreach döngülerinde dizi referanslarının klonlanmamış olduğu bir hataydı.

+0

Merak ediyorum, problemi açıklayamadım! :-) – L84

+0

“Global $ simpsons” ı, aynı diziye ve dolayısıyla aynı işaretçiye atıfta bulunduğunu düşünüyordum. Ama, 'foreach'ın işaretçiyi sıfırladığını gördüm, bu yüzden sorun olmadığını düşündüm. Öyle görünüyor. :-) –

İlgili konular