Till: \r, \n oder \r\n ?

Moin!

Wenn ich eine Text Datei mit PHP erstelle was sollte ich dann an jedes Zeilenende setzen? \r, \n oder \r\n ?

rgds Till

  1. Hi,

    Wenn ich eine Text Datei mit PHP erstelle was sollte ich dann an jedes Zeilenende setzen? \r, \n oder \r\n ?

    kurze Antwort: ja.

    Längere Antwort: Nimm das, das dem/den auswertendem/n System/en am besten passt.

    Cheatah

    --
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
  2. Hallo,

    Wenn ich eine Text Datei mit PHP erstelle was sollte ich dann an jedes Zeilenende setzen? \r, \n oder \r\n ?

    Wer oeffnet die Datei nachher?
    Unter welchem Betriebssystem? Mit welchem Programm?
    Als was (text/plain, text/html, ...)?

    Mit \r\n solltest Du normalerweise auf der sicheren Seite sein.
    Eventuell reicht auch \n.

    http://www.tiptom.ch/homepage/faq.html?q=zeilenumbruch

    Gruesse,

    Thomas

    --
    Bitte keine Mails mit Fachfragen - dafuer gibt es das Forum!
    Ich mag es, wenn URLs verlinkt sind (</faq/#Q-19>).
    Oft gestellte PHP-Fragen beantwortet die dclp-FAQ bestens: http://www.dclp-faq.de/
    1. Hallo Thomas,

      Mit \r\n solltest Du normalerweise auf der sicheren Seite sein.

      Nein. Mit diesen symbolischen Konstanten ist man *nicht* auf der
      sicheren Seite. \n wird, abhängig von der Umgebung, bei der Ausgabe
      mal nach \015\012 konvertiert, mal nach \012, mal nach \015.
      Wenn man auf der *sicheren* Seite sein will, nennt man explizit,
      was man haben will: \015\012 bzw. \012 bzw. \015.

      http://www.tiptom.ch/homepage/faq.html?q=zeilenumbruch

      Da fehlt mir ein Hinweis auf die Autokonvertierung von \n nach
      \015\012 bzw. \015 bzw. \012. Eine unter Windows im ASCII-Modus
      geschriebene Datei (z. B. fwrite($fd,"abc\nabc\n")) ergibt
      "abc\015\012abc\015\012". Liest man die Datei unter Windows ein,
      so ergibt das im Programm wieder "abc\nabc\n". Liest man dieselbe
      Datei dagegen unter UNIX ein (vorrausgesetzt, sie wurde nicht
      automatisch konvertiert, z. B. durch den ASCII-Modus von
      FTP-Programmen), so gibt das "abc\015\nabc\015\n".

      Grüße,
       CK

      --
      Sein oder nicht sein, das ist hier die Frage!
      1. Hallo,

        http://www.tiptom.ch/homepage/faq.html?q=zeilenumbruch
        Da fehlt mir ein Hinweis auf die Autokonvertierung von \n nach
        \015\012 bzw. \015 bzw. \012.

        Danke fuer die Erlaeuterungen.

        Ich hatte bisher dem folgendem Manual-Abschnitt geglaubt:
        http://www.php.net/manual/en/language.types.string.php#AEN3528
        (Tabelle 6-1, siehe auch mein Posting [pref:t=71954&m=414348] von 15:02h)

        Durch diesen Thread wurde mir klar, dass es bei
        Datei-Operationen einige Problemchen gibt,
        und ich werde meine Seite entsprechend aendern
        und auch auf diesen Thread verlinken, sobald
        er im Archiv ist.

        Gruesse,

        Thomas

        --
        Bitte keine Mails mit Fachfragen - dafuer gibt es das Forum!
        Ich mag es, wenn URLs verlinkt sind (</faq/#Q-19>).
        Oft gestellte PHP-Fragen beantwortet die dclp-FAQ bestens: http://www.dclp-faq.de/
  3. Halihallo Till

    Wenn ich eine Text Datei mit PHP erstelle was sollte ich dann an jedes Zeilenende setzen? \r, \n oder \r\n ?

    Sollen? - Es gibt, wie du weisst, mehrere Möglichkeiten wie man das
    Ende einer Zeile kodiert. Richtig sind alle. Falls du die Textdatei
    für ein bestimmte Plattform schreiben möchtest, verwende die z.B.
    okale Schreibweise "\015" (Mac), "\012" (Unix/*) oder "\015\012"
    (Win).
    Noch etwas: Sei vorsichtig mit "\n" oder "\r". Bei Perl z.B. ist
    "\n" je nach Plattform einmal "\015\012", "\015" und "\012". Genauso
    die von libc definierte Konstante "\n". PHP tanzt hier anscheinend
    aus der Reihe und definiert \n generell als Oktalwert \015. Aber
    hier ist wirklich vorsicht geboten, also verwendet man im
    Zweifelsfall einfach die entsprechende Oktalschreibweise, dann hat
    man absolute Sicherheit.

    Viele Grüsse

    Philipp

    1. Hallo Philipp,

      PHP tanzt hier anscheinend
      aus der Reihe und definiert \n generell als Oktalwert \015.

      Ja, aber: Wenn man eine Datei schreibt, und beim Öffnen *nicht* das Flag 'b' mit angegeben wurde (also fopen (..., 'w') und *nicht* fopen (..., 'wb')), dann wird \n (und auch \015!) automatisch zum Zeilenumbruch des jeweiligen Betriebsystems verwandelt (und beim Lesen natürlich genau umgekehrt).

      Daher: Textdateien *nie* mit dem Flag 'b' öffnen und *immer* \n verwenden und PHP macht es dann für das Betriebsystem genau richtig.

      Viele Grüße,
      Christian

      1. Halihallo Christian

        Daher: Textdateien *nie* mit dem Flag 'b' öffnen und *immer* \n verwenden und PHP macht es dann für das Betriebsystem genau richtig.

        Ach herje, mein Fehler. Ich hab's vorhin (doch) gerade ausprobiert.
        Bei meinem Test lag es nicht am Flag 'b', sondern an dem Einlesen
        von Perl, welches CRLF automatisch wieder in LF umgewandelt hat...
        Das hat mir den Irrglauben aufgebunden, dass PHP \n automatisch mit
        LF kodiert (obwohl ich eigentlich hätte merken müssen, dass es
        eigentlich CR sein sollte, wenn man der Login von "\n\r" folgt)...
        Schande über mich :-)

        Fakt: Wenn man Textdateien für die aktuelle Platform schreiben
        möchte: \n verwenden. Falls nicht: Die Zeichen "hart-kodiert" als
        Oktal-/Hexadezimalzeichen schreiben um Fehler zu vermeiden für einen
        guten Code[tm]...   (hoffe, das ist jetzt richtig ;))

        Viele Grüsse

        Philipp

        1. Halihallo Christian

          Ach herje, mein Fehler. Ich hab's vorhin (doch) gerade ausprobiert.
          Bei meinem Test lag es nicht am Flag 'b', sondern an dem Einlesen
          von Perl, welches CRLF automatisch wieder in LF umgewandelt hat...
          Das hat mir den Irrglauben aufgebunden, dass PHP \n automatisch mit
          LF kodiert (obwohl ich eigentlich hätte merken müssen, dass es
          eigentlich CR sein sollte, wenn man der Login von "\n\r" folgt)...

          Stopp... Ich hab's doch in Perl mit binmode() eingelesen, Perl sollte
          also jedes Byte genauso lassen, wie es ist.

          test.php: (schreiben)
          <?php
            $fh = fopen("test.txt", "w");
            fwrite($fh,"\n");
            fclose($fh);
          ?>

          test.pl: (einlesen und ASCII-Dump)
          open( F, '<./test.txt' );
          binmode(F);
          my $t = '';
          while ( read(F,$t,1) ) {
            print ord($t)."\n";
          }
          close(F);

          Nach Aufruf von test.php habe ich auf einem Windows-Rechner eine
          Datei test.txt liegen, die genau ein Byte(!) aufweist (nach
          Explorer). Der Perl-ASCII-Dump zeigt auch nur ein Zeichen, nämlich:
          10 (\012). Obwohl die Datei a) zwei Bytes haben sollte und b) der
          ASCII-Dump auf 10 13 lauten sollte.

          Kann es sein, dass ich den Wald grad vor lauter Bäumen nicht mehr
          sehe, oder habe ich einfach ein Unixisches PHP auf einem Windows-
          Rechner?

          Die Schlussfolgerung ist doch richtig, dass mein PHP anscheinend \n
          mit dem ASCII-Wert 10 füttert, obwohl es eigentlich "\015\012" in die
          Datei schreiben sollte (logisches Newline für Windows-Systeme).
          Falls nicht, würde a) Perl das physikalische Newline (CRLF) in das
          logische, interne LF umwandeln und Explorer(!) würde dasselbe machen.
          Nun, M$ traue ich zwar einiges zu, aber eine Datei hat nunmal eine
          eindeutig definierte Byte-Grösse, unabhängig von logischen Newlines
          (gezählt werden die physikalisch vorhandenen).

          ? :-)

          Viele Grüsse

          Philipp

          1. Hallo Philipp,

            Kann es sein, dass ich den Wald grad vor lauter Bäumen nicht mehr
            sehe, oder habe ich einfach ein Unixisches PHP auf einem Windows-
            Rechner?

            Aus http://php.net/fopen:

            |Note: Different operating system families have different
            |line-ending conventions. When you write a text file and want to
            |insert a line break, you need to use the correct line-ending
            |character(s) for your operating system. Unix based systems use
            |\n as the line ending character, Windows based systems use \r\n
            |as the line ending characters and Macintosh based systems use \r
            |as the line ending character.

            |If you use the wrong line ending characters when writing your
            |files, you might find that other applications that open those
            |files will "look funny".

            |Windows offers a text-mode translation flag ('t') which will
            |transparently translate \n to \r\n when working with the file. In
            |contrast, you can also use 'b' to force binary mode, which will
            |not translate your data. To use these flags, specify either 'b'
            |or 't' as the last character of the mode parameter.

            |The default translation mode depends on the SAPI and version of
            |PHP that you are using, so you are encouraged to always specify
            |the appropriate flag for portability reasons. You should use the
            |'t' mode if you are working with plain-text files and you use \n
            |to delimit your line endings in your script, but expect your files
            |to be readable with applications such as notepad. You should use
            |the 'b' in all other cases.

            |If you do not specify the 'b' flag when working with binary files,
            |you may experience strange problems with your data, including
            |broken image files and strange problems with \r\n characters.

            Und, das wichtigste:

            |For portability, it is strongly recommended that you always use
            |the 'b' flag when opening files with fopen().

            |Again, for portability, it is also strongly recommended that you
            |re-write code that uses or relies upon the 't' mode so that it
            |uses the correct line endings and 'b' mode instead.

            |As of PHP 4.3.2, the default mode is set to binary for all
            |platforms that distinguish between binary and text mode. If you
            |are having problems with your scripts after upgrading, try using
            |the 't' flag as a workaround until you have made your script more
            |portable as mentioned above.

            Grüße,
             CK

            --
            Der Verstand ist der Hausherr, der Koerper sein Gast.
            1. Halihallo Christian, Halihallo Thomas

              [...]
              Ich sollte etwas mehr die Doku lesen... Immerhin war meine
              Feststellung korrekt, es besteht also noch Hoffung :-)

              Danke an euch beide :-)

              Viele Grüsse

              Philipp

          2. Hallo zusammen,

            Ich erlaube mir, hier noch auf zwei Stellen
            im PHP-Manual hinzuweisen:

            http://www.php.net/manual/en/language.types.string.php#AEN3528

            Table 6-1. Escaped characters

            sequence  meaning
            \n        linefeed (LF or 0x0A (10) in ASCII)
            \r        carriage return (CR or 0x0D (13) in ASCII)

            Also gilt AFAICT grundsaetzlich:
            \n = Dez. 10 = Oct. 12 = Hex. 0A
            \r = Dez. 13 = Oct. 15 = Hex. 0D

            Die Sache wird ausfuehrlich diskutiert auf der Seite zu fopen():
            http://www.php.net/manual/en/function.fopen.php
            "When you write a text file and want to insert a line
            break, you need to use the correct line-ending character(s)
            for your operating system.
            [...]
            Windows offers a text-mode translation flag ('t')
            which will transparently translate \n to
            \r\n when working with the file.  In contrast, you
            can also use 'b' to force binary mode, which will not
            translate your data.  To use these flags, specify either
            'b' or 't' as the last character of the mode parameter."

            Diese automatische Umwandlungs-Geschichte steht soweit
            ich es verstehe also nur unter Windows zur Verfuegung,
            und auch dann nur, wenn man es ausdruecklich festlegt.

            Gruesse,

            Thomas

            1. Hallo Thomas,

              Diese automatische Umwandlungs-Geschichte steht soweit
              ich es verstehe also nur unter Windows zur Verfuegung,
              und auch dann nur, wenn man es ausdruecklich festlegt.

              Nein. Die automatische Umwandlungsgeschichte ist aktiv abhängig
              von der PHP-Version (bzw. genauer von der SAPI-Version). Wie in
              meinem Posting aus dem Manual zitiert:

              |The default translation mode depends on the SAPI and version of
              |PHP that you are using,

              Grüße,
               CK

              --
              So, wie ein Teil ist, ist das Ganze.