inspiron: eine bestimmte Zeile aus csv mit php auslesen

Hallo,
ich möchte eine bestimmte einzelne Zeile aus einer csv Datei auslesen.
Im Moment zeigt er mir die ersten beiden Zeilen.
Wie kann ich zum Bsp. nur die Zeile 5 anspringen?

Gruß

  
<table border="0" rules="groups">  
    <?php  
    $handle = fopen("urlaub.csv", "r");						  
	$i = 0;  
    while(($data = fgetcsv($handle, 150, ";")) && $i < 2)  
     {  
  
    echo "<tr>";  
        echo "<td width=\"300px\">". $data[0]."</td>";  
        echo "<td width=\"25px\">". $data[1]."</td>";  
        echo "<td width=\"25px\">". $data[2]."</td>";  
        echo "<td width=\"25px\">". $data[3]."</td>";  
        echo "<td width=\"25px\">". $data[4]."</td>";  
        echo "<td width=\"25px\">". $data[5]."</td>";  
        echo "<td width=\"25px\">". $data[6]."</td>";  
        echo "<td width=\"25px\">". $data[7]."</td>";  
        echo "<td width=\"25px\">". $data[8]."</td>";  
        echo "<td width=\"25px\">". $data[9]."</td>";  
        echo "<td width=\"25px\">". $data[10]."</td>";  
        echo "<td width=\"25px\">". $data[11]."</td>";  
        echo "<td width=\"25px\">". $data[12]."</td>";  
        echo "<td width=\"25px\">". $data[13]."</td>";  
        echo "<td width=\"25px\">". $data[14]."</td>";  
        echo "<td width=\"25px\">". $data[15]."</td>";  
        echo "<td width=\"25px\">". $data[16]."</td>";  
        echo "<td width=\"25px\">". $data[17]."</td>";  
        echo "<td width=\"25px\">". $data[18]."</td>";  
        echo "<td width=\"25px\">". $data[19]."</td>";  
        echo "<td width=\"25px\">". $data[20]."</td>";  
        echo "<td width=\"25px\">". $data[21]."</td>";  
        echo "<td width=\"25px\">". $data[22]."</td>";  
        echo "<td width=\"25px\">". $data[23]."</td>";  
        echo "<td width=\"25px\">". $data[24]."</td>";  
        echo "<td width=\"25px\">". $data[25]."</td>";  
        echo "<td width=\"25px\">". $data[26]."</td>";  
        echo "<td width=\"25px\">". $data[27]."</td>";  
        echo "<td width=\"25px\">". $data[28]."</td>";  
        echo "<td width=\"25px\">". $data[29]."</td>";  
        echo "<td width=\"25px\">". $data[30]."</td>";  
        echo "<td width=\"25px\">". $data[31]."</td>";  
    echo "</tr>"; 											  
	$i ++;  
    }  
    fclose($handle);  
    ?>  
</table>  

  1. Hi,

    ich möchte eine bestimmte einzelne Zeile aus einer csv Datei auslesen.
    Im Moment zeigt er mir die ersten beiden Zeilen.
    Wie kann ich zum Bsp. nur die Zeile 5 anspringen?

    „Anspringen“ kannst du sie gar nicht.

    Du kannst aber die Zeilen davor in der Verarbeitung ignorieren (und ggf. nach der Verarbeitung der fünften Zeile das weitere Auslesen abbrechen), wenn du einfach die Zeilennummer selber mit hochzählst und abfragst.

    MfG ChrisB

    --
    “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
  2. Hallo inspiron,

    Hallo,
    ich möchte eine bestimmte einzelne Zeile aus einer csv Datei auslesen.
    Im Moment zeigt er mir die ersten beiden Zeilen.
    Wie kann ich zum Bsp. nur die Zeile 5 anspringen?

    Gruß

    <?php
        $handle = fopen("urlaub.csv", "r");
    $i = 0;
        while(($data = fgetcsv($handle, 150, ";")) && $i < 2)
         {

    echo "<tr>";

    foreach($data as $val){

    echo "<td width="300px">". $val."</td>";

    }

    echo "</tr>";
    $i ++;
        }
        fclose($handle);
        ?>

      
    fgetcsv() liest Zeilenweise aus einer Source. Durch die Bedingung `($i < 2)`{:.language-php} der while-Schleife werden jeweils nur die ersten beiden Zeilen ausgegeben. Wenn Du speziell eine Bestimmte Zeile auslesen willst, kannst Du die gesamten ausgelesenen Daten in ein Array ablegen, was pro Index-Schlüssel einer Zeile entspricht:  
      
    ~~~php
    $data  =array();  
    $handle=fopen("urlaub.csv","r");  
      
    while($data[]=fgetcsv($handle,150,";");  
      
    fclose($handle);  
      
    // Ausgabe Zeile 5, wobei ein array mit 0 zu zählen beginnt:  
    echo "<tr>";  
    foreach($date[4] as $val){  
        echo "<td width=\"300px\">". $val."</td>";  
    }  
    echo "</tr>"; 
    

    Zum nachlesen für Dich: Datentyp Array, foreach()

    Gruß aus Berlin!
    eddi

    1. Hallo Eddi,
      dankeschön, genau so sollte es sein!
      Nur wie formatiere ich jetzt die Spalten?

      echo "<td width=\"300px\">". $val."</td>";

      Die erste sollte 300px breit und die anderen 30, 25px breit sein.

      Gruß

      ...auch aus Berlin

      1. Re:

        Nur wie formatiere ich jetzt die Spalten?

        Wenn Du meinst, wie Du eine spezielle Spalte mit echo ausgibst, kann auch hier wieder eine Schleife, in dem Fall for(), die Lösung für Dich sein.
        Wenn Du etwas anderes mit „formatiere[n]” meintest, frage bitte nochmals genauer nach!

        Gruß aus Berlin!
        eddi

      2. Entschuldige, Du hast ja alles geschrieben, was Du willst.

        echo "<td width=\"300px\">". $val."</td>";

        Die erste sollte 300px breit und die anderen 30, 25px breit sein.

        Das ist an sich eine Sache, die nichts mehr mit PHP zu tun hat. Mir erscheint es hier sinnvoll, die Weite der Spalten vorzuformatiern. Sieh Dir dazu bitte <colgroup> an!

        ...auch aus Berlin

        Atschö! (Da komme ich her ;)

        1. Hallo,
          ich habe da noch ein Problem.

          Ich möchte aus ca 15 csv Dateien je eine bestimmte (zBsp. die 5.)Zeile auslesen und diese untereinder anzeigen. Kann ich mit " fopen" mehrere Dateien öffnen oder gibt es eine andere Möglichkeit?

          1. Hi,

            Ich möchte aus ca 15 csv Dateien je eine bestimmte (zBsp. die 5.)Zeile auslesen und diese untereinder anzeigen. Kann ich mit " fopen" mehrere Dateien öffnen

            Natürlich kannst du.
            Am besten nacheinander, und in einer Schleife - dann lässt sich die bestehende Lösung für eine Datei wiederverwenden.

            oder gibt es eine andere Möglichkeit?

            Von PHP aus kaum eine andere (sinnvolle), als alle zu durchsuchenden Dateien einzeln zu öffnen.

            MfG ChrisB

            --
            “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
            1. Natürlich kannst du.
              Am besten nacheinander, und in einer Schleife - dann lässt sich die bestehende Lösung für eine Datei wiederverwenden.

              Hallo,
              ich habe da mal folgendes versucht, aber finde den Fehler nicht.
              echo $files[$i]; zeigt mir: name_A_2010.csvname_B_2010.csvname_C_2010.csv

              Nur wird die 5.Zeile von der ersten "name_A_2010.csv" 3mal untereinander angezeigt.

                
              <table border="1" >  
                
              <?php  
              //$data = array();  
              $files = array( 'name_A_2010.csv',  
                              'name_B_2010.csv',  
                              'name_C_2010.csv');  
                
              for ($i=0; $i<sizeof($files); $i++)  
              {  
                echo $files[$i];  
                $handle = fopen($files[$i],"r");  
                while($data[] = fgetcsv($handle, 150, ";"))  
                {  
                }  
                fclose($handle);  
                
              // Ausgabe Zeile 5  
              echo "<tr>";  
              foreach($data[4] as $val){  
                  echo "<td width=\"800px\">". $val."</td>";  
              }  
              }  
              echo "</tr>";  
                
              ?>  
              </table>  
              
              
              1. Hallo,

                for ($i=0; $i<sizeof($files); $i++)
                {
                  echo $files[$i];
                  $handle = fopen($files[$i],"r");
                  while($data[] = fgetcsv($handle, 150, ";"))
                  {
                  }
                  fclose($handle);

                bis hierher hast du die erste der drei csv-Dateien gelesen, den Inhalt hast du in $data[], ein Datensatz nach dem anderen.

                foreach($data[4] as $val){
                    echo "<td width="800px">". $val."</td>";

                Und dann gibst du die Felder von Datensatz #4 der Reihe nach aus. Okay, 800px pro Spalte ist wohl reichlich dimensioniert ...

                Das Dumme ist: In $data[4] ist auch im zweiten Schleifendurchlauf, also wenn bereits die zweite Datei ausgewertet wird, immer noch der Datensatz aus der ersten Datei, weil du mit $data[]= immer nur ein weiteres Arrayelement am Ende des Arrays anfügst.
                Vielleicht möchtest du $data[] am Ende jedes Schleifendurchlaufs wieder löschen?

                Übrigens: Ein HTML-Verschachtelungsfehler ist auch noch drin; das </tr> wird an der falschen Stelle gesetzt.

                Ciao,
                 Martin

                --
                Um mit einem Mann glücklich zu werden, muss eine Frau ihn sehr gut verstehen und ein bisschen lieben.
                Um mit einer Frau glücklich zu werden, muss ein Mann sie sehr lieben und darf gar nicht erst versuchen, sie zu verstehen.
                1. ...dankeschön,
                  ich habs mal so probiert und es funktioniert.

                    
                  foreach($data[5] as $val){  
                      echo "<td width=\"800px\">". $val."</td>";  
                  }  
                  unset($data);  
                  
                  

                  echo "<td width="800px">". $val."</td>";

                  Und dann gibst du die Felder von Datensatz #4 der Reihe nach aus. Okay, 800px pro Spalte ist wohl reichlich dimensioniert ...

                  Tja,
                  das mit der Spaltenbreite bekomme ich nicht hin.
                  Die 800px stammen noch aus 'nem Test.
                  Ich weiß nicht wie ich es machen soll das die erste Spalte 300px und die restlichen 25px breit sein sollen.

                  Gruß

              2. Hallo inspiron,

                <?php  
                $files= array(  'name_A_2010.csv',  
                                'name_B_2010.csv',  
                                'name_C_2010.csv'  
                );  
                $data ='';  
                $table="\n";  
                $head ='<col width="300">';  
                $count=0;  
                  
                // Zelleninhalt ($table) festlegen  
                for ($i=0; $i<sizeof($files); $i++){  
                	echo $files[$i];  
                	$handle = fopen($files[$i],"r");  
                	for($j=0;$data = fgetcsv($handle, 150, ";");$j++){  
                		// Jeweils 5. Zeile  
                		if($j==4){  
                			$table.="<tr>\n<td>".implode("</td>\n<td>",$data)."</td>\n</tr>";  
                			$count =($count<($c=count($data))) ? $c : $count;  
                		}  
                	}  
                	fclose($handle);  
                }  
                // Zellengröße ($head) festlegen  
                for($i=0;$i<$count;$i++){  
                	$head.='<col width="25">'  
                }  
                  
                ?>
                
                <html>  
                <!-- etc. -->  
                <table border="1">  
                 <colgroup>  
                  [code lang=php]<?php echo $head;?>
                

                </colgroup>
                 <?php echo $table;?>
                </table>
                <!-- etc. -->[/code]

                Gruß aus Berlin!
                eddi

                1. Hallo,
                  danke erst einmal, komme leider erst jetzt dazu mich zu bedanken.

                  Folgende Meldung wird angezeigt und finde das Problem nicht
                  Parse error: syntax error, unexpected '}' in /is/.......php  on line 27

                  Gruß

                  1. ....ich habe es nun doch gefunden, das ";" hat gefehlt!
                    $head.='<col width="25">';

                    Großen Dank für die Hilfe!

  3. Hi,

    ich möchte eine bestimmte einzelne Zeile aus einer csv Datei auslesen.

    schön. Da CSV-Dateien rein textbasiert sind und im Normalfall keine feste Satzlänge haben, kannst du die gesuchte Zeile nicht direkt anspringen. Du musst also vom Dateianfang aus die ersten n-1 Zeilen lesen und ignorieren.

    Im Moment zeigt er mir die ersten beiden Zeilen.

    Wer ist "er"?

    Wie kann ich zum Bsp. nur die Zeile 5 anspringen?

    Indem du viermal fgetcsv() aufrufst und die Ergebnisse jeweils wegwirfst, um dann die Ergebnisse des fünften Aufrufs zu verwenden.

    Bei sehr kleinen Dateien könnte man noch mit file() den gesamten Dateiinhalt lesen. Mit file() erhält man ein Array, jedes Element entspricht dann einer Zeile der Datei. So kann man auch auf die gesuchte Zeile direkt zugreifen. Anstatt fgetcsv() würde man dann den einzelnen String mit str_getcsv() behandeln, wenn man PHP 5.3 hat; ansonsten müsste man das behelfsmäßig nachbilden, indem man den String an den Kommas explodiert.

    So long,
     Martin

    --
    Die junge Ehefrau weint sichbei ihrer Mutter aus:
    Er hat gesagt, ich soll mich zum Teufel scheren! - Und da kommst du ausgerechnet zu mir?!
    1. Hallo Martin,

      Bei sehr kleinen Dateien könnte man noch mit file() den gesamten Dateiinhalt lesen. Mit file() erhält man ein Array, jedes Element entspricht dann einer Zeile der Datei.

      ja. Einer Zeile der Datei, aber nicht einem Datensatz einer CSV-Datei.

      So kann man auch auf die gesuchte Zeile direkt zugreifen.

      Nein. Die Zeile in der Datei muss nicht mit dem gesuchten Datensatz übereinstimmen. Ich gehe davon aus, dass inspiron meint, dass er den fünften Datensatz haben möchte.

      Du übersiehst hier die Möglichkeit, dass Elemente einer CSV-Datei sehr wohl Zeilenumbrüche enthalten dürfen. fgetcsv() berücksichtigt dies, file() nicht.

      Freundliche Grüße

      Vinzenz

      1. Hallo Vinzenz,

        Bei sehr kleinen Dateien könnte man noch mit file() den gesamten Dateiinhalt lesen. Mit file() erhält man ein Array, jedes Element entspricht dann einer Zeile der Datei.
        ja. Einer Zeile der Datei, aber nicht einem Datensatz einer CSV-Datei.

        stimmt, Leerzeilen gibt's ja auch. *schande*

        Nein. Die Zeile in der Datei muss nicht mit dem gesuchten Datensatz übereinstimmen. Ich gehe davon aus, dass inspiron meint, dass er den fünften Datensatz haben möchte.

        Davon gehe ich auch aus.

        Du übersiehst hier die Möglichkeit, dass Elemente einer CSV-Datei sehr wohl Zeilenumbrüche enthalten dürfen. fgetcsv() berücksichtigt dies, file() nicht.

        Das ist interessant - gibt's das in irgendeiner Spezifikation oder einem Quasi-Standard? Dass Zeilenumbrüche innerhalb eines Feldes bzw. Datensatzes vorkommen können, höre ich zum ersten Mal.
        Ich hatte noch nicht das Bedürfnis, Strings mit Zeilenumbrüchen (oder überhaupt mit Steuerzeichen) in CSV-Dateien zu speichern; aber wenn, hätte ich es mit einem üblichen Escaping reralisiert, z.B. Backslash-n als Zeilenumbruch.

        So long,
         Martin

        --
        Rizinus hat sich angeblich als sehr gutes Mittel gegen Husten bewährt.
        1. Hallo Martin,

          Das ist interessant - gibt's das in irgendeiner Spezifikation oder einem Quasi-Standard? Dass Zeilenumbrüche innerhalb eines Feldes bzw. Datensatzes vorkommen können, höre ich zum ersten Mal.
          Ich hatte noch nicht das Bedürfnis, Strings mit Zeilenumbrüchen (oder überhaupt mit Steuerzeichen) in CSV-Dateien zu speichern; aber wenn, hätte ich es mit einem üblichen Escaping reralisiert, z.B. Backslash-n als Zeilenumbruch.

          Media-Type text/csv wird in RFC 4180 beschreiben. Für Dich ist hier Abschnitt 2, Nummer 6 interessant.

          Gruß aus Berlin!
          eddi

          1. Hallo,

            Dass Zeilenumbrüche innerhalb eines Feldes bzw. Datensatzes vorkommen können, höre ich zum ersten Mal.
            Media-Type text/csv wird in RFC 4180 beschreiben. Für Dich ist hier Abschnitt 2, Nummer 6 interessant.

            gut, danke. Das ist eine klare Aussage, auch wenn sie ja ein wenig mit 2.1 ("Each record is located on a separate line, delimited by a line break (CRLF)") kollidiert.

            Zum Glück ergeben sich daraus für mich keine Hausaufgaben (Bugfixes bei älteren Projekten), weil ich CSV bisher nur entweder als Ausgabeformat angeboten oder als internes Format für Konfigurationsdaten verwendet habe. Das Lesen von CSVs aus Fremdquellen hat mich noch nicht getroffen.

            Ciao,
             Martin

            --
            Dieser Satz wurde in mühsamer Kleinstarbeit aus einzelnen Wörtern zusammengesetzt.
              (Hopsel)
            1. Hi,

              Das ist eine klare Aussage, auch wenn sie ja ein wenig mit 2.1 ("Each record is located on a separate line, delimited by a line break (CRLF)") kollidiert.

              Die ist wohl (nur) so zu verstehen, dass keine zwei Datensätze in einer Zeile stehen können.

              „[D]elimited by a line break” ist ein Datensatz ja eben nicht, wenn der line break Bestandteil der Daten ist, und entsprechend maskiert wurde.

              Also könnte man sich höchstens an dem „on *a* separate line“ stören, wenn man das wörtlich als *genau* *eine* Zeile nimmt.

              MfG ChrisB

              --
              “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
          2. Hallo,

            Das ist interessant - gibt's das in irgendeiner Spezifikation oder einem Quasi-Standard? Dass Zeilenumbrüche innerhalb eines Feldes bzw. Datensatzes vorkommen können, höre ich zum ersten Mal.

            Media-Type text/csv wird in RFC 4180 beschreiben. Für Dich ist hier Abschnitt 2, Nummer 6 interessant.

            ich find's interessant, dass die IETF bei der Registrierung dieses Mediatyps so nachlässig vorgegangen ist :-( Immerhin weist die dritte Referenz auf die Verwendung eines Separator-Zeichens hin, die die RFC genauso wie die beiden anderen angeführten Quellen das Separatorzeichen mit dem Komma gleichsetzen, was bei der ersten Quelle besonders lustig ist, weil sie speziell auf Excel hinweisen, das hier in mancher Hinsicht einen Quasistandard definiert.

            Angabe eines Separatorzeichens - wie es fgetcsv() ermöglicht - ist bei uns praktisch Pflicht. Das Semikolon, das hierzulande das Standardlistentrennzeichen von Windows ist (deutschsprachige Windows-Standardinstallation), führt die Rangliste hierzulande nach meiner Erfahrung mit riesigem Vorsprung an.

            Bei PHP wird's aber auch wieder lustig, wenn man CSV-Dateien in UTF-8-Zeichencodierung erstellt und auf die Idee kommt, das Paragraphenzeichen § als Trennzeichen nutzen zu wollen ...

            Freundliche Grüße

            Vinzenz

            1. Hi,

              Bei PHP wird's aber auch wieder lustig, wenn man CSV-Dateien in UTF-8-Zeichencodierung erstellt und auf die Idee kommt, das Paragraphenzeichen § als Trennzeichen nutzen zu wollen ...

              Dafür, dass PHP (noch) keine korrekte Vorstellung vom Begriff „Zeichen“ hat, kann aber das Format nichts :-)

              MfG ChrisB

              --
              “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
              1. Hallo Chris,

                Bei PHP wird's aber auch wieder lustig, wenn man CSV-Dateien in UTF-8-Zeichencodierung erstellt und auf die Idee kommt, das Paragraphenzeichen § als Trennzeichen nutzen zu wollen ...

                Dafür, dass PHP (noch) keine korrekte Vorstellung vom Begriff „Zeichen“ hat, kann aber das Format nichts :-)

                nö, kein Vorwurf ans Format. Ich hoffe nur, dass Lebensdauer von PHP5 sowie Entwicklungsdauer von PHP6 sich nicht an Perl 5 und Perl 6 orientieren ...

                Freundliche Grüße

                Vinzenz