Onkel Schnitzel: Problem mit rekursiver Erstellung eines mehrd. Array

Hallo liebes Forum,

nach langer Zeit ich mal wieder. Ich tüftle nun seit zwei Tagen und raufe mir die Haare. Ich möchte eine Verzeichnisstruktur auslesen und diese dann in ein mehrdimensionales assoziatives Array schreiben, um sie als fertig strukturierte Liste per AJAX an ein Script zu übergeben (war so meine Idee). Nun merke ich aber, dass Rekursionen irgendwie nicht meins sind, da setzt mein Verstand aus. Ich zeig euch mal, was ich bis jetzt zusammengeferkelt hab:

  
$z=0; // Testzähler, um zu überprüfen, ob und in welcher Ebene die Funktion aufgerufen wird  
  
function readdirs($pfad, $mainArray = '', $z){  
 	  
	// Verzeichnis scannen und in Array speichern  
    $verzArray=scandir($pfad);  
	echo $z;  
    foreach($verzArray as $ordner) {  
  
		if(!preg_match('/^(.|..)$/i', $ordner)) {  
			  
			// wenn Ordnerelement ein Ordner ist, neues Unterarray erstellen und die Funktion damit neu aufrufen  
			if(is_dir($pfad.$ordner)) {				  
				$mainArray[$ordner] = array();			  
				readdirs($pfad.$ordner.'/', $mainArray[$ordner],$z+1);   	  
			}	  
			// sonst die Datei im Array numerisch ablegen  
			else {  
				$mainArray[] = $ordner;  
			}  
		}  
    }  
	return($mainArray);  
}  
  
$ausgabe = readdirs('../../OptikBilder/Galerie/');  
  
echo '<pre>'; print_r($ausgabe); echo '</pre>';  
  

Die erste Array-Ebene wird erstellt, danach ist Schluss. Die Funtkion wird aber artig ausgeführt, das sieht man am Testzähler $z. Nur das Array wird nicht entsprechend erweitert. Mir fällt grad nichts mehr ein. Ich hab aber das Gefühl, dass nicht mehr viel fehlt. Könnt ihr mir auf die Sprünge helfen?

Besten Dank schonmal

  1. Hi,

      	// wenn Ordnerelement ein Ordner ist, neues Unterarray erstellen und die Funktion damit neu aufrufen  
      	if(is_dir($pfad.$ordner)) {				  
      		$mainArray[$ordner] = array();			  
      		readdirs($pfad.$ordner.'/', $mainArray[$ordner],$z+1);   	  
    
      
    Deine Funktion hat einen Rückgabewert – aber mit dem machst du hier nichts.  
      
    Warum packst du ihn nicht in dein Array …?  
      
    MfG ChrisB  
      
    
    -- 
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    
    1.   	// wenn Ordnerelement ein Ordner ist, neues Unterarray erstellen und die Funktion damit neu aufrufen  
        	if(is_dir($pfad.$ordner)) {				  
        		$mainArray[$ordner] = array();			  
        		readdirs($pfad.$ordner.'/', $mainArray[$ordner],$z+1);   	  
      
      
      >   
      > Deine Funktion hat einen Rückgabewert – aber mit dem machst du hier nichts.  
      >   
      > Warum packst du ihn nicht in dein Array …?  
      >   
      > MfG ChrisB  
      >   
      >   
        
      Puuh, ich schwitze, mein Kopf ist leer. Ich hatte mir gedacht, der Rückgabewert spielt nur für die Ausgabe des Gesamt-Arrays eine Rolle. Das ist ja im Moment wohl auch so. Ich hab ehrlich gesagt keine Ahnung, wie ich den im "laufenden Betrieb" ins Array kriegen soll. Als Parameter an die Funktion übergeben, oder wie? Muss ich den dann vorher global zwischenspeichern?  Ohje...   
      
      1. Puuh, ich schwitze, mein Kopf ist leer. Ich hatte mir gedacht, der Rückgabewert spielt nur für die Ausgabe des Gesamt-Arrays eine Rolle. Das ist ja im Moment wohl auch so. Ich hab ehrlich gesagt keine Ahnung, wie ich den im "laufenden Betrieb" ins Array kriegen soll. Als Parameter an die Funktion übergeben, oder wie? Muss ich den dann vorher global zwischenspeichern?  Ohje...

        Du bist auch schon nah an der Lösung ;-) Du übergibst ein Array an die Funktion, füllst es und gibst es zurück, allerdings Benutzt du den den Rückgabewert nicht, also wird für alle Ebenen, bis auf die letzte, das gefüllte Array weggeworfen.
        Funktionieren sollte das ganze indem du den rekursiven Aufruf so änderst:

          
        $mainArray[$ordner] = readdirs($pfad.$ordner.'/', array(), $z+1);   	  
        
        
        1. Du bist auch schon nah an der Lösung ;-) Du übergibst ein Array an die Funktion, füllst es und gibst es zurück, allerdings Benutzt du den den Rückgabewert nicht, also wird für alle Ebenen, bis auf die letzte, das gefüllte Array weggeworfen.
          Funktionieren sollte das ganze indem du den rekursiven Aufruf so änderst:

          $mainArray[$ordner] = readdirs($pfad.$ordner.'/', array(), $z+1);

            
          Aaaaaah, es geht! Jetzt weiß ich auch, was Chris meinte. Ich musste den Rückgabewert der Rekursiv-Funktion innerhalb der Funktion nochmal abspeichern, damit dieser dann wiederum per return mit zurückgegeben wird. Im Grunde nur eine klitzekleine Änderung, aber ich wäre nicht drauf gekommen. Super, vielen Dank euch beiden!  
            
            
          Es passiert übrigens noch eine seltsame Sache. Wenn ich versuche den Funktionsnamen zu ändern, bekomme ich diese Fehlermeldung: "Fatal error: Cannot redeclare readdir()"...  
            
          So, meine Suche hat jetzt ergeben, dass readdir() offenbar auch eine PHP-eigene Funktion ist. In diesem Zusammenhang würde ich verstehen, wenn eine Fehlermeldung beim Anlegen per function readdir() kommt. Dass die nun aber, im Gegenteil dann kommt, wenn ich den "Konflikt" beseitigen will, finde ich sehr rätselhaft. Wer kanns erklären? :-)  
            
           
          
          1. Es passiert übrigens noch eine seltsame Sache. Wenn ich versuche den Funktionsnamen zu ändern, bekomme ich diese Fehlermeldung: "Fatal error: Cannot redeclare readdir()"...

            So, meine Suche hat jetzt ergeben, dass readdir() offenbar auch eine PHP-eigene Funktion ist. In diesem Zusammenhang würde ich verstehen, wenn eine Fehlermeldung beim Anlegen per function readdir() kommt. Dass die nun aber, im Gegenteil dann kommt, wenn ich den "Konflikt" beseitigen will, finde ich sehr rätselhaft. Wer kanns erklären? :-)

            Ok, Kommando zurück. Ich sollte Schluss machen für heute. Genau das Gegenteil war der Fall. Ich hab sie ja umbenannt von readdirs in readdir und dann kam der Fehler. Also im Grunde ists dann doch so, wie ichs mir auch gedacht hätte. Alles klar, danke nochmal.