Jörg: Warum bleibt mein Array leer?

Hallo,

ich hatte mir das so schön ausgedacht.
Ich lese ein Verzeichnis (mit vielen Unterverzeichnissen auf 1. Ebene und innerhalb dieser ausschließlich Dateien) rekursiv ein und packe alles in ein zweidimensionales Array. Aber mein Array bleibt leer und ich finds nicht, woran es liegt.

meine Kontrollausgaben

function dir_rekursiv($verzeichnis)
{
    $handle =  opendir($verzeichnis);
    while ($datei = readdir($handle))
    {
        if ($datei != "." && $datei != "..")
        {
            if (is_dir($verzeichnis.$datei)) // Wenn Verzeichniseintrag ein Verzeichnis ist, dann Kopie für den Key des Arrays
            {
                $verz = $datei;
                // Erneuter Funktionsaufruf, um das aktuelle Verzeichnis auszulesen
                dir_rekursiv($verzeichnis.$datei.'/');
            }
            else
            {
                // Wenn Verzeichnis-Eintrag eine Datei ist, diese in Value des Array
                $arr_Date['".$verz."'] = $datei;
                }
        }
    }
    closedir($handle);
    return $arr_Date;
}

$arr_Date = dir_rekursiv('../../myDir/');

echo "<pre>";
print_r($arr_Date);

Hm, vorhin wurde mir noch ein leeres Array ausgegeben, aktuell gar nichts mehr. Ich habe sicher schon zuviel dran herum gewurschtelt. Die Idee ist aber sicher klar geworden, oder?

Warum bekomme ich so nicht mein gewüschtes Array?

Jörg

  1. Warum bekomme ich so nicht mein gewüschtes Array?

    Zusatz:

    Mir geht es darum, zu verstehe, wo mein Denkfehler liegt.

    Eine fertige Funktion, die mein Ziel realisiert, habe ich längst gefunden.

    function dirToArray($dir) {
        $contents = array();
        foreach (scandir($dir) as $node) {
            if ($node == '.' || $node == '..') continue;
            if (is_dir($dir . '/' . $node)) {
                $contents[$node] = dirToArray($dir . '/' . $node);
            } else {
                $contents[] = $node;
            }
        }
        return $contents;
    }
    
  2. Deine Variable $arr_Date ist auch bei einem rekursiven Aufruf der Funktion (== neue Instanz oder Tochterinstanz) zunächst leer... Das heisst die Tochterinstanz der Funktion darf nicht in Mutters Schatzkästlein sehen oder gar darin etwas verändern. „Der Mutti geben und die tuts dann rein“ ist die Regel.

    // Erneuter Funktionsaufruf, um das aktuelle Verzeichnis auszulesen
    dir_rekursiv($verzeichnis.$datei.'/');
    

    Du musst die Rückgaben übernehmen, wie Du es wenige Zeilen später ja auch tust:

    // Wenn Verzeichnis-Eintrag eine Datei ist, diese in Value des Array
    $arr_Date['".$verz."'] = $datei;
    

    By the Way: Warum bust die Quotas mit in die Namen ein? Rest von Trial & Error? Das würde jedes Mal einen Key ".$verz." erzeugen, also immer diesen und mit GENAU diesen Zeichen.

    $arr_Date[$verz] = $datei;
    

    genügt wohl.

    1. Und was willst Du denn überhaupt als Ergebnis haben?

      Ich hab's gerade so umgeschrieben, das Werte wie

      [27]=>
        string(42) "/home/fastix/Dokumente/2022-07-13-0002.pdf"
      

      erscheinen.

      Für die exakt 463298 Dateien in meinem Home braucht das Ding 1m41,997s…

    2. Hallo Willi,

      By the Way: Warum bust die Quotas mit in die Namen ein? Rest von Trial & Error? Das würde jedes Mal einen Key ".$verz." erzeugen, also immer diesen und mit GENAU diesen Zeichen.

      $arr_Date[$verz] = $datei;
      

      genügt wohl.

      Jaja, damit hatte ich angefangen, der Rest ist tatsächlich der Rest von Trial und error. Dacht, dass php seit Vers. 8 die Keys von Arrays zwingend als String in Anführungszeichen benötigt.

      Deine Variable $arr_Date ist auch bei einem rekursiven Aufruf der Funktion (== neue Instanz oder Tochterinstanz) zunächst leer... Das heisst die Tochterinstanz der Funktion darf nicht in Mutters Schatzkästlein sehen oder gar darin etwas verändern. „Der Mutti geben und die tuts dann rein“ ist die Regel.

      Ich war mir dessen bewußt, dass es etwas mit dem rekursiven Aufruf, einem eventuellen Überschreiben von Variablen/Arrays oder dem Gültigkeitsbereich von Variablen zu tun haben muss.
      Leider bringt mich Dein Hinweis auch nicht weiter, er verwirrt mich eher noch mehr. 😅

      Und was ich haben will, ist einfach:

      Du erinnerst Dich an Dein DB-Backupscript und die hierdurch erzeugte Verzeichnisstruktur. Und ich bau grad ein Frontend, um später mal innerhalb dessen (falls nötig) ein Backup wieder einspielen zu können.

      Dazu will ich wissen, welche Tage mit welchen Dumps verfügbar sind.
      Dazu dachte ich mir, wäre es schön, ein Mehrdimensionals Array zu haben, das ich nach Datum (also Key) sortieren kann (woran ich grad verzweifle, weil ich multisort irgendwie nicht verstehe).

      Jörg

      1. Hallo Jörg,

        Ich habe den Thread so genau nicht verfolgt, das war mir zu linuxig.

        Wenn Du diese Verzeichnisstruktur hast

        backups\
           2022-08-30\
              dump1
              dump2
              dump3
           2022-08-31\
              dump1
              dump2
              dump4
        

        und Du den backups-Ordner einliest, wie genau soll dann dein Array aussehen? So?

        [
           "2022-08-30" => [ "dump1", "dump2", "dump3" ],
           "2022-08-31" => [ "dump1", "dump2", "dump4" ]
        ]
        

        Rolf

        --
        sumpsi - posui - obstruxi
      2. Dazu dachte ich mir, wäre es schön, ein Mehrdimensionals Array zu haben, das ich nach Datum (also Key) sortieren kann (woran ich grad verzweifle, weil ich multisort irgendwie nicht verstehe).

        Wozu das denn?

        Nehmen wir an, Du hast:

        Backups/
           + 2022-01-01/
               + foo.sql
               + bar.sql
           + 2022-02-01/ 
               + foo.sql
               + bar.sql
        

        ergibt:

        2022-01-01/foo.sql,
        2022-01-01/bar.sql,
        2022-02-01/foo.sql,
        2022-02-01/bar.sql
        

        Das ist schnödes eindimensionales Array.

        1. 2022-01-01/foo.sql,
          2022-01-01/bar.sql,
          2022-02-01/foo.sql,
          2022-02-01/bar.sql
          

          Das ist schnödes eindimensionales Array.

          Das hab ich jetzt mal verwürfelt übernommen und als Liste von Listen ausgegeben:

          <?php
          $arr=[
          '2022-01-01/foo.sql',
          '2022-02-01/bar.sql',
          '2022-01-01/bar.sql',
          '2022-02-01/foo.sql'
          ];
          
          sort( $arr );
          
          ### Wir brauchen das erste Verzeichnis:
          list( $oldDir, $tmp ) = explode( '/', $arr[0] );
          
          echo "
          <ol>
          	<li>$oldDir
          		<ol>";
          
          foreach ( $arr as $item ) {
          	list( $dir, $fileName ) = explode( '/', $item );
              if 	( $dir == $oldDir ) {
          		echo "
          			<li>$fileName</li>";
              } else { ###Verzeichniswechsel
          		echo "
          		</li>
          	 </li>
          	 <li>$dir
          		<ol>
          			<li>$fileName</li>";
          		$oldDir = $dir; ### Nicht vergessen 😇
              }
          }
          
          echo "
          		</ol>
          	</li>
          </ol>";
          

          Resultat:

          <ol>
          	<li>2022-01-01
          		<ol>
          			<li>bar.sql</li>
          			<li>foo.sql</li>
          		</li>
          	 </li>
          	 <li>2022-02-01
          		<ol>
          			<li>bar.sql</li>
          			<li>foo.sql</li>
          		</ol>
          	</li>
          </ol>
          
      3. Hallo Jörg,

        (woran ich grad verzweifle, weil ich multisort irgendwie nicht verstehe).

        Dafür brauchst Du Multisort auch nicht. Den nimmst Du, wenn Du mehr als ein Array hast und diese Arrays als Spalten einer zu sortierenden Tabelle auffassen willst.

        Rolf

        --
        sumpsi - posui - obstruxi