Axel Richter: Rekursive Funktion - Problme mit return!

Beitrag lesen

Hallo,

function dateien($open, $dateien, $system) {
if($open['0'] != "") {

...

dateien($puffer, $dateien, $system);
}
else {
  return $dateien;
}
}


>   
>   
> Nun habe ich folgendes Problem:  
> Return gibt eine leere Variable aus, d.h. nicht den Array mit den Unterordnern drin. Die Funktion funktioniert allerdings, da wenn mann return mit print\_r() ersetzt, alle Dateien und Ordner richtig ausgegeben werden!  
  
Ich habe den Code oben eingekürzt, um das Problem zu zeigen. Leider unterscheiden viele Sprachen nicht mehr explizit zwischen Funktionen, die Werte zurückgeben und Methoden bzw. Subroutinen, die etwas machen ohne Werte zurückzugeben. Bei PHP ist es so, dass eine function auch ohne explizites return immer einen Wert zurückgibt. Ist kein return angegeben, dann wird NULL zurückgegeben.  
  
Was passiert hier nun? Im Prinzip möchtest Du eine Funktion haben, welche ein Array als Wert zurückgibt. Beim rekursiven Aufruf verwendest Du aber die selbe Funktion rekursiv wie eine Methode. Du rufst sie rekursiv immer wieder auf, \_ohne\_ dass sie zu einem expliziten return kommen könnte. Innerhalb der Rekursion macht sie also etwas an dem Array, gibt aber immer NULL und \_nicht\_ das Array zurück. Dadurch füllt sich der Stack mit Methodenscopes in denen das Array durchaus die gewünschten Werte hat, die aber mit dem Funktionsscope gar nichts zu tun haben. Wird die Rekursion dann beendet und kommt die Funktion durch return nun wieder in Ihren Funktionsscope zurück, müssen erst alle Methodenscopes im Stack wieder rückwärts durchlaufen werden. Am Schluss wird NULL zurückgegeben.  
  
Beispiel, welches das zeigt:  
  
~~~php
  
<?php  
function rekursion($v) {  
 if ($v < 10) {  
  rekursion(++$v);  
 } else {  
  print "Else-Zweig erreicht ";  
  return $v;  
 }  
 print "\$v: $v, ";  
}  
var_dump(rekursion(1));  
?>  

Normalerweise würde man meinen, dass das print "\$v: $v, "; gar nicht erreicht werden dürfte. Wird es aber doch, und zwar _nach_ erreichen des Else-Zweiges _während_ des return-Vorganges.

Was geschehen muss ist, dass eine Funktion auch in der Rekursion immer eine Funktion mit explizitem return bleiben muss.

  
<?php  
function rekursion2($v) {  
 if ($v < 10) {  
  return rekursion2(++$v);  
 } else {  
  print "Else-Zweig erreicht ";  
  return $v;  
 }  
 print "\$v: $v, ";  
}  
var_dump(rekursion2(1));  
?>  

In Deinem Fall:

function dateien($open, $dateien, $system) {
if($open['0'] != "") {

...
     return dateien($puffer, $dateien, $system);

}
else {
  return $dateien;
}
}

  
Das aber nur zur Erklärung, warum Dein Funktions-Methoden-Mix am Schluss NULL zurückgibt.  
  
Ansonsten solltest Du Toms Hinweis beherzigen, denn diese Aufgabe - alle Unterordner und Dateien des Ordners "dateien" in den Array $dateien speichern - ist durchaus eine Standardaufgabe, für die es sicherlich auch in PHP bereits gut durchdachte fertige Lösungen gibt.  
  
viele Grüße  
  
Axel