[PHP] Bis zum Ende der Zeile auslesen



  • Hallo,
    ich habe eine CSV-Datei deren Inhalt ich Zeichen für Zeichen auslese um dann die einzelnen Werte in Strings zu schreiben. Folgendes hatte ich versucht um zu prüfen ob das Ende der Zeile erreicht ist und damit ein neuer Datensatz anfängt:

    while($chr != '\n')
    {
     ...
    }
    

    Nun bekomme ich folgenden Fehler:

    Fatal error: Maximum execution time of 20 seconds exceeded in /srv/www/htdocs/scripts/csv.php on line 13
    

    Das ist genau die Zeile wo die Schleife beginnt.
    Wie kann ich prüfen ob das Ende der Zeile erreicht ist, wenn nicht so???



  • Niklas Cathor schrieb:

    Hallo,
    [..]

    while($chr != '\n')
    {
     ...
    }
    

    [..]
    Wie kann ich prüfen ob das Ende der Zeile erreicht ist, wenn nicht so???

    Genau so sollte es gehen. Vielleicht noch auf Windows Newlines mit '\r\n' prüfen.
    Dein Fehler lässt auf gigantisch lange Zeilen oder eine Endlosschleife schließen. Poste mal den Code, der in der While-Schleife steht. :xmas1:



  • Das ist die gesamte Schleife:

    while($chr!='\n')
    {
       $i = 0;
       while($chr!=',')
       {
          sprintf($feld[$i],"%c",$chr);
          $chr = fgetc($file);
          echo $chr;
       }
       $i++;
    }
    


  • Es fällt mir gerade erst auf, aber in '' werden imho normalerweise bis auf \' keine Escape-Sequenzen verarbeitet. Du musst also entweder direkt den ASCII-Code dafür eingeben (war das jetzt 10 oder 13 - eines ist \n und das andere \r). Aber da du ja von fgetc sowieso auch nen Strng bekommst kannst du auch einfach "\n" verwenden 🙂



  • Hmm... ja... das ändert leider auch nichts. Ich habe festgestellt, dass das oben gepostete sowieso nicht funktionieren kann ^^ $i steigt nie, da es sowieso sofort wieder auf 0 gesetzt wird...

    Hier mal die aktuelle Version:

    while($chr!=EOF) // <-- Die Schleife wird endlos ausgeführt
    {
       $i = 0;
       while($chr != "\n" && $chr != "\r\n" && chr != "\r")
       {
          if($chr == "\"")
          {
             $chr = fgetc($file);
             while($chr!="\"")
             {
                sprintf($feld[$i],"%c",$chr);
                $chr = fgetc($file);
             }
             $i++;
          }
          $chr = fgetc($file);
       }
       $query  = "INSERT INTO friaul(feld1,feld2,feld3,feld4,feld5,feld6,feld7,feld8,feld9)
                  VALUES ('".$feld[0]."', '".$feld[1]."', '".$feld[2]."', '".$feld[3]."', '".$feld[4]."', '".$feld[5]."', '".$feld[6]."', '".$feld[7]."', '".$feld[8]."')";
       for($i=0;$i<9;$i++)
         echo $feld[$i]."<br>\n"; // <-- Hier gibt er nur leere Zeilen aus
       $result = mysql_query($query);
    }
    

    Ein weiteres Problem ist, dass die Zeichen nie im Array landen. Es werden nur leere Zeilen ausgegeben, wo eigentlich Strings landen sollten. Bis dann irgendwann ein Timeout kommt, weil die Datei aus irgendeinem Grund nie bis zum Ende gelesen wird. Dabei hat sie nur 10 Zeilen mit je ca. 100 Zeichen.

    Ich bin das ganze schon hundertmal durchgegangen ohne den Fehler zu finden. Entweder ich bin zu blind oder zu blöd 🙄
    Vielleicht findet ja jemand den Fehler...
    Danke im Voraus



  • Mir ist irgendwie nicht so ganz klar, was du überhaupt erreichen willst 🙄
    Hier mal was du machst:
    - Zeichen für Zeichen durchgehen bis zum Ende der Datei
    - währenddessen aus jeder Zeile die einzelnen Strings in "" detektieren und davon jeweils das letzte Zeichen in einem Array ablegen
    - am Ende der Zeile die Felder aus dem Array (beinhalten jeweils das letzte Zeichen der Strings bzw. falls es nicht so viele gab Müll / den Inhalt von der letzten Zeile)in einer DB speichern und ausgeben

    Hoffe ich habe das nicht falsch interpretiert. Und noch was: Du liest immer nur einZeichen ein, also werden in $chr wohl nie 2 drinnen stehen ("\r\n")

    BTW: Du kannst mit der Funktion file() auch direkt eine Datei in ein Array einlesen...
    Evtl. solltest du dir auch mal reguläre Ausdrücke anschauen 🙂



  • Das timeout sollte ja nicht das Problem sein aber tortzdem: set_time_limit(0) schaltet das timelimit ab, wenn dein PHP Dings nicht im Safe-Mode laeuft.



  • noobie schrieb:

    set_time_limit(0) schaltet das timelimit ab

    ... was allerdings bei so ziemlich jedem Provider nicht funktionieren wird; aus gutem Grund!



  • Ich hab nur gesagt wie man das abstellen kann... z.B kann eine DB abfrage auf ein nicht indexiertes Attribut in einer DB mit 5 Millionen Datensätzen sehr langsam werden, auch wenn man nur 2 Rows erwartet. Natürlich versuchen die Provider sich so gut wie möglich zu schützen, dennoch gibt es diese Funktion nicht Grundlos. 🙂



  • wraum nicht mit fgets ne komplette zeile einlesen und mit explode zerlegen? ungefähr so?

    $FileHandle = fopen($FileName, "r");
    
    while (!feof($FileHandle))
    {
    	$Line      = fgets($FileHandle, 4096); // 4096 Zeichen oder bis Zeilenende lesen
    	$LineArray = explode(";", $Line);      // am Separator (hier Semikolon) aufspalten
    
    // ... was machen
    }
    
    fclose($FileHandle);
    

Anmelden zum Antworten