enrico: txt-Datei einlesen -> Bildung eines 2-dimensionalen(?) Arrays

Hallo und guten Abend,

ich habe eine txt-Datei mit folgendem Aufbau:

Nr|Titel|Inhalt|Genre|FSK
   Nr|Titel|Inhalt|Genre|FSK
   Nr|Titel|Inhalt|Genre|FSK

Wenn ich nachfolgende Array-Struktur hinbekäme...

$Film[0]["Nr"] = 0;
   $Film[0]["Titel"] = "ORIGINAL SIN";
   $Film[0]["Inhalt"] = "Im Kuba des ausgehenden 19. Jahrhunderts...";
   $Film[0]["Genre"] = "Drama/Thriller";
   $Film[0]["FSK"] = 16;

...dann müßte ich über nachfolgenden Code nach einer beliebigen Spalte sortieren können:

global $key;

$test = multi_sort($test, $key = 'points');

function multi_sort($array, $akey)
   {
      function compare($a, $b)
      {
         global $key;
         return strcmp($a[$key], $b[$key]);
      }

usort($array, "compare");
      return $array;
   }

Natürlich müßte ich den aktuellen Eintrag "points" durch eine der vorhandenen Spalten
ersetzen.

Nur ist mein Problem, das ich die Erzeugung des Arrays offensichtlich nicht hinbekomme.

Die txt-Datei wird wie folgt eingelesen und das Array wie folgt aufgebaut:

function Inhalt_ausgeben ($Dateiname)
   {
      $Dateizeiger = fopen ($Dateiname, "r");

if ($Dateizeiger)
      {
         while (!feof ($Dateizeiger))
         {
            $Zeile  = fgets ($Dateizeiger);
            $Spalte = explode("|", $Zeile);

$Film[]["Nr"]     = $Spalte[0];
            $Film[]["Titel"]  = $Spalte[1];
            $Film[]["Inhalt"] = $Spalte[2];
            $Film[]["Genre"]  = $Spalte[3];
            $Film[]["FSK"]    = $Spalte[4];

...HTML-Code zur Ausgabe der Daten...

}

fclose ($Dateizeiger);
      }
   }

Wenn ich nun allerdings den folgenden Wert ausgeben lassen will, dann wird mir nichts
angezeigt:

echo $Film[28]["Titel"];

Die txt-Datei hat aktuell 29 Einträge, so dass mit dem Wert 28 der letzte Eintrag
eigentlich angezeigt werden müsste.

Was muß ich korrigieren, damit mein Vorhaben klappt?

Vielen Dank für Eure Unterstützung.

Viele Grüße,
Enrico

  1. Hallo,

    Wenn ich nun allerdings den folgenden Wert ausgeben lassen will, dann wird mir nichts angezeigt:

    echo $Film[28]["Titel"];

    Die txt-Datei hat aktuell 29 Einträge, so dass mit dem Wert 28 der letzte Eintrag eigentlich angezeigt werden müsste.

    in solchen und allen ähnlichen Fällen, in denen Variablen anscheinend nicht den erwarteten Wert haben, kann man sich schnell selbst helfen, indem man einfach den Variableninhalt mit var_dump() ausgeben lässt (dann im Quellcode der Seite nachschauen, nicht auf die normale Browseranzeige verlassen).

    Grüße, Peter

    1. Hallo Peter,

      danke für Deine rasche Rückantwort.

      Ich bekomme den Wert "null" im Browserfenster angezeigt, somit wurde hier nichts übergeben.

      Ich habe aber schon mehrmals meine verwendete Schreibweise für die Erzeugung mehrdimensionaler
      Arrays im Internet gesehen.

      Ich versteh's nicht...

      Viele Grüße,
      Enrico

      1. Hi,

        Ich bekomme den Wert "null" im Browserfenster angezeigt, somit wurde hier nichts übergeben.

        Und welche Variable hast du jetzt ueberprueft?

        MfG ChrisB

        1. Hi ChrisB,

          Ich habe folgende Ausgabe eingeleitet:

          var_dump($Film[28]["Titel"]);

          Viele Grüße,
          Enrico

          1. Hi,

            Ich habe folgende Ausgabe eingeleitet:

            var_dump($Film[28]["Titel"]);

            Etwas cleverer waere es, var_dump($Film) zu benuzten - um sich dann mal anzuschauen, wie $Film denn ueberhaupt aufgebaut ist.

            MfG ChrisB

            1. Hi ChrisB,

              hier erhalte ich eine ewig lange Ausgabe am Bildschirm mit - ausschnittsweise - folgendem Aufbau:

              array(145) {
              [0]=> array(1) { ["Nr"]=> string(1) "1" }
              [1]=> array(1) { ["Titel"]=> string(30) "LIGHTHOUSE - INSEL DES GRAUENS" }
              [2]=> array(1) { ["Inhalt"]=> string(515) "Mitten auf dem Ozean und während..." }
              [3]=> array(1) { ["Genre"]=> string(15) "Horror/Thriller" }
              [4]=> array(1) { ["FSK"]=> string(4) "16 " }
              ...
              }

              Also scheint der Fehler in der Ansprechung einzelner Werte zu liegen ?!

              Viele Grüße,
              Enrico

              1. Hi,

                array(145) {
                [0]=> array(1) { ["Nr"]=> string(1) "1" }
                [1]=> array(1) { ["Titel"]=> string(30) "LIGHTHOUSE - INSEL DES GRAUENS" }
                [2]=> array(1) { ["Inhalt"]=> string(515) "Mitten auf dem Ozean und während..." }
                [3]=> array(1) { ["Genre"]=> string(15) "Horror/Thriller" }
                [4]=> array(1) { ["FSK"]=> string(4) "16 " }
                ...
                }

                Also scheint der Fehler in der Ansprechung einzelner Werte zu liegen ?!

                Wie ich gleich schon zu Anfang schrieb, legst du fuer *jeden* Wert, den du auf "zweiter Ebene" ablegen moechtest, auch einen neuen Eintrag auf erster Ebene an - eben dadurch, dass du *jedes* Mal $Film[]... verwendest.
                Wenn du das nicht willst - dann mach' es nicht :-)
                (Ueberlege dir bitte zunaechst selber, was man stattdessen machen koennte.)

                MfG ChrisB

                1. Hallo ChrisB,

                  ich will es ja... :-)

                  Wäre folgende Notation besser ?

                  $Film = array(
                        "Nr"     => $Spalte[0],
                        "Titel"  => $Spalte[1],
                        "Inhalt" => $Spalte[2],
                        "Genre"  => $Spalte[3],
                     );

                  Wenn ja, wie muß ich es in den "while (!feof ($Dateizeiger))"-Block einbauen?

                  Viele Grüße,
                  Enrico

                  1. Hallo ChrisB & Peter,

                    jetzt klappt es absolut perfekt :-)

                    Kein Fehler bei der Ausgabe, Ausgabe so wie gewünscht, wunderbar :-)

                    Vielen Dank für Eure Unterstützung...

                    Viele Grüße,
                    Enrico

              2. array(145) {

                Nanu, die Datei soll doch nur 29 Einträge haben?

                [0]=> array(1) { ["Nr"]=> string(1) "1" }
                [1]=> array(1) { ["Titel"]=> string(30) "LIGHTHOUSE - INSEL DES GRAUENS" }
                [2]=> array(1) { ["Inhalt"]=> string(515) "Mitten auf dem Ozean und während..." }
                [3]=> array(1) { ["Genre"]=> string(15) "Horror/Thriller" }
                [4]=> array(1) { ["FSK"]=> string(4) "16 " }

                Jetzt wird's klar, so läuft das natürlich nicht:

                $Film[]["Nr"]     = $Spalte[0];
                $Film[]["Titel"]  = $Spalte[1];
                $Film[]["Inhalt"] = $Spalte[2];
                $Film[]["Genre"]  = $Spalte[3];
                $Film[]["FSK"]    = $Spalte[4];

                Mit jedem Aufruf von $Film[] hängst du einen neuen Eintrag an $Film an. Deshalb steckt in $Film[0] nur "Nr", in $Film[1] nur "Titel", usw. Du möchtest aber alle fünf Eigenschaften in einen Eintrag haben.

                Du musst erst ein Feld mit den Filmdaten erzeugen und dieses dann anschließend an $Film anhängen:

                $f = Array();
                $f["Nr"]     = $Spalte[0];
                $f["Titel"]  = $Spalte[1];
                $f["Inhalt"] = $Spalte[2];
                $f["Genre"]  = $Spalte[3];
                $f["FSK"]    = $Spalte[4];
                $Film[] = $f;

                Gruß, Peter

                1. Hi,

                  Du musst erst ein Feld mit den Filmdaten erzeugen und dieses dann anschließend an $Film anhängen:

                  $f = Array();
                  $f["Nr"]     = $Spalte[0];
                  $f["Titel"]  = $Spalte[1];
                  $f["Inhalt"] = $Spalte[2];
                  $f["Genre"]  = $Spalte[3];
                  $f["FSK"]    = $Spalte[4];
                  $Film[] = $f;

                  Oder auch bspw.

                  $Film[] = array(
                              'Nr' => $Spalte[0],
                              'Titel' => $Spalte[1],
                              ...
                            );

                  MfG ChrisB

                2. Hallo Peter,

                  Dein Vorschlag scheint mein Problem zu lösen:

                  array(29)
                     {
                        [0]=> array(5)
                        {
                           ["Nr"]=> string(1) "1"
                           ["Titel"]=> string(30) "LIGHTHOUSE - INSEL DES GRAUENS"
                           ["Inhalt"]=> string(515) "Mitten auf dem Ozean und während..."
                           ["Genre"]=> string(15) "Horror/Thriller"
                           ["FSK"]=> string(4) "16 "
                        }
                        ...
                     }

                  Es sind 29 Filme erfasst mit jeweils 5 Spalten und den jeweiligen Inhalten.

                  Kann ich die einzelnen Einträge nun über beispielsweise $Film[2]["Titel") ansprechen ?

                  Viele Grüße,
                  Enrico

                  1. Moin.

                    Kann ich die einzelnen Einträge nun über beispielsweise $Film[2]["Titel") ansprechen ?

                    Was passiert, wenn du es versuchst?

                    Christoph

            2. var_dump($Film[28]["Titel"]);

              Etwas cleverer waere es, var_dump($Film) zu benuzten - um sich dann mal anzuschauen, wie $Film denn ueberhaupt aufgebaut ist.

              So meinte ich es.

              Falls auch $Film leer ist, var_dump($Film) so nahe an die Leseschleife schieben, bis was drin ist, zur Not auch in die Schleife rein und zusammen mit var_dump($Zeile) und var_dump($Spalte).

  2. Hi,

    while (!feof ($Dateizeiger))
             {
                $Zeile  = fgets ($Dateizeiger);
                $Spalte = explode("|", $Zeile);

    $Film[]["Nr"]     = $Spalte[0];

    Was macht $arrayVariable[] = ...?
    Es erzeugt einen neuen Eintrag im Array.

    $Film[]["Titel"]  = $Spalte[1];

    Und was macht es wohl hier?

    $Film[]["Inhalt"] = $Spalte[2];

    Und hier?

    Und ...

    wird mir nichts angezeigt:

    echo $Film[28]["Titel"];

    Die txt-Datei hat aktuell 29 Einträge, so dass mit dem Wert 28 der letzte Eintrag eigentlich angezeigt werden müsste.

    *Seufz*, ihr Kiddies sollt nicht immer "annehmen", was in Variablen drinstehen "muesste" - sondern verflixt noch mal *kontrollieren*, bspw. mittels var_dump.

    MfG ChrisB

    1. Hallo ChrisB,

      ich halte Dir jetzt mal zugute, dass Dein "ihr Kiddies" nicht so gemeint war, wie es
      unter Umständen vermuten ließe...

      Wenn man nicht immer annehmen darf, was drinstehen müsste, warum gibt es dann diese
      Schreibweise ?

      Meiner Meinung nach kann es sich nur um einen kleinen Fehler, leider mit großer Wirkung
      handeln.

      Viele Grüße
      Enrico

      1. Hi,

        ich halte Dir jetzt mal zugute, dass Dein "ihr Kiddies" nicht so gemeint war, wie es unter Umständen vermuten ließe...

        Es ist in dem Sinne gemeint, dass einfach "anzunehmen", in einer Variable muesste irgendwas bestimmtes drinstehen, weil man schliesslich "glaubt", es richtig programmiert zu haben, kein Programmieren ist, sondern Rumstuempern auf Scriptkiddie-Niveau.

        Man nimmt nicht an, sondern man *kontrolliert*.

        Wenn man nicht immer annehmen darf, was drinstehen müsste, warum gibt es dann diese Schreibweise ?

        Die Schreibweise $arrayvariable[] = ... gibt es, weil sie durchaus nuetzlich zum Anfuegen eines neuen Elements an ein Array ist -

        Meiner Meinung nach kann es sich nur um einen kleinen Fehler, leider mit großer Wirkung handeln.

        • du willst aber nicht fuer jeden Einzelwert ein neues Arrayelement auf der ersten Ebene anfuegen. Sondern nur genau *eins*, welches dann seinerseits wieder ein Array darstellt.

        MfG ChrisB

  3. Hello,

    wenn Du immer nur genau nach einer Spalte sortieren willst, ist das einfacher zu lösen:

    ich habe eine txt-Datei mit folgendem Aufbau:

    Nr|Titel|Inhalt|Genre|FSK
       Nr|Titel|Inhalt|Genre|FSK
       Nr|Titel|Inhalt|Genre|FSK

    Wenn ich nachfolgende Array-Struktur hinbekäme...

    $Film[0]["Nr"] = 0;
       $Film[0]["Titel"] = "ORIGINAL SIN";
       $Film[0]["Inhalt"] = "Im Kuba des ausgehenden 19. Jahrhunderts...";
       $Film[0]["Genre"] = "Drama/Thriller";
       $Film[0]["FSK"] = 16;

    Mach stattdessen eine Struktur

    $_film['nr'][$i]
         $_film['titel'][$i]
         $_film['inhalt'][$i]
         $_film['genre'][$i]
         $_film['fsk'][$i]

    Die einzelnen Felder eines Datansatzes korrespondiern dann immer übner den Index des Datensatzes.
    Der Vorteil ist aber, dass jede Spalte der Tabelle in einem eigenen Array steht und man so nach jeder Spalte mit den einfachen Array-Sortierungsfunktionen von PHP sortieren kann.

    Mann muss das Gesamtkunstwerk dann nur nach der sortierten Spalte als Leitspalte anzeigen lassen

    Du musst das Array nur nach $sortcol sortieren lassen z.B. mit natsort($_film[$sortcol])

    $sortcol = 'genre';
    natsort($_film[$sortcol]);

    und dann kannst Du es sortiert ausgeben.

    $zeile = "<table>\n";

    foreach($_film[$sortcol] als $key => $val)
    {
      $zeile .= "  <tr>\n";
      $zeile .= "    <td>". $_film['nr'][$key] . "</td>\n";
      $zeile .= "    <td>". $_film['titel'][$key] . "</td>\n";
      $zeile .= "    <td>". $_film['inhalt'][$key] . "</td>\n";
      $zeile .= "    <td>". $_film['genre'][$key] . "</td>\n";
      $zeile .= "    <td>". $_film['fsk][$key] . "</td>\n";
      $zeile .= "  </tr>\n";
    }

    $zeile .= "</table>\n";

    Das schöne daran ist, dass Du alle (einfachen) Sortierungen gleichzeitig vorhalten kannst, was sich natürlich nur lohnt, wenn das Array entweder in der Session (oder sonstwo permanent) geparkt wird oder Du es in einem Scriptdurchlauf in den unterschiedlichen Sortierungen benötigst...

    Ein harzliches Glückauf

    Tom vom Berg

    http://bergpost.annerschbarrich.de
    .

    --
    Nur selber lernen macht schlau