Kiedy używam stałej PHP „PHP_EOL”?


360

Kiedy warto używać PHP_EOL?

Czasami widzę to w przykładach kodu PHP. Czy to rozwiązuje problemy z końcem DOS / Mac / Unix?


1
Myślę, że w opiniach na tej stronie jest wiele mylących porad. Jeśli uruchomisz skrypt na dwóch różnych platformach, a następnie porównaj dane wyjściowe lub wygenerowane dane (pliki dziennika, strona HTML, rekordy bazy danych itp.), Wówczas PHP_EOL spowoduje niezgodność w różnicach. W większości przypadków nie tego chcesz.
donquixote

Odpowiedzi:


357

Tak, PHP_EOLjest rzekomo używany do znalezienia znaku nowej linii w sposób zgodny z wieloma platformami, więc obsługuje problemy DOS / Unix.

Zauważ, że PHP_EOL reprezentuje znak końca dla bieżącego systemu. Na przykład nie znajdzie linii końcowej Windows, gdy zostanie wykonany w systemie uniksopodobnym.


9
Czy należy go używać jako znaku końca linii podczas pisania skryptu wiersza poleceń?
Thomas Owens,

5
@Andre: A może ktoś, kto pisze aplikacje do zainstalowania, używania i wdrażania przez innych? Czy sugerujesz, że powinny one ograniczyć swoje „obsługiwane platformy” do * nix?
Cylindryczny

1
@Stann - To, co wiesz o „dużych projektach”, nie jest decydującym czynnikiem najlepszej praktyki, nie mówiąc już o tym, co jest lub nie jest przydatne. Utrzymuję „duży projekt”, który jest częściowo wdrażany na kilku hostach, w tym na niektórych serwerach Windows. Nie zakładaj - stałe nic nie ranią i są doskonale poprawnym sposobem pisania kodu neutralnego dla platformy. Twoje przeciwne komentarze są nieco absurdalne.
Chris Baker,

5
Nie, nie sądzę, żeby twoja odpowiedź była prawidłowa. Generujesz kod w jednym systemie, ale wysyłasz dane wyjściowe do innego systemu. PHP_EOL informuje jednak o ograniczniku zakończenia linii TYLKO dla systemu, w którym jest używany. Nie gwarantuje to, że drugi system używa tego samego separatora. Zobacz moją odpowiedź poniżej.
StanE

1
ale nie używaj PHP_EOLdanych wysłanych z formularza.
Nabi KAZ

88

Od main/php.hwersji PHP 7.1.1 i wersji 5.6.30:

#ifdef PHP_WIN32
#   include "tsrm_win32.h"
#   include "win95nt.h"
#   ifdef PHP_EXPORTS
#       define PHPAPI __declspec(dllexport)
#   else
#       define PHPAPI __declspec(dllimport)
#   endif
#   define PHP_DIR_SEPARATOR '\\'
#   define PHP_EOL "\r\n"
#else
#   if defined(__GNUC__) && __GNUC__ >= 4
#       define PHPAPI __attribute__ ((visibility("default")))
#   else
#       define PHPAPI
#   endif
#   define THREAD_LS
#   define PHP_DIR_SEPARATOR '/'
#   define PHP_EOL "\n"
#endif

Jak widać PHP_EOLmoże być "\r\n"(na serwerach Windows) lub "\n"(na czymkolwiek innym). W wersjach PHP wcześniejszych niż 5.4.0RC8 istniała trzecia możliwa wartość PHP_EOL: "\r"(na serwerach MacOSX). To było złe i zostało naprawione 2012-03-01 z błędem 61193 .

Jak już powiedzieli Ci inni, możesz użyć PHP_EOLdowolnego rodzaju danych wyjściowych (gdzie dowolna z tych wartości jest poprawna - takich jak: HTML, XML, logi ...), w których chcesz ujednoliconych znaków nowej linii . Pamiętaj, że to serwer określa wartość, a nie klient. Użytkownicy Windowsa uzyskają wartość z Twojego serwera Unix, co czasami jest dla nich niewygodne.

Chciałem tylko pokazać możliwe wartości PHP_EOLpopierane przez źródła PHP, ponieważ jeszcze go tu nie pokazano ...


3
Łał. Programiści PHP mylą się co do tego. Jako link do Wikipedii wspominasz, Mac OS 9 i wcześniej używał „\ r”, ale nie OS X, który używa „\ n”. Ktoś powinien zgłosić raport o błędzie ...
imgx64

27
@ imgx64 Tak, może, ale szczerze mówiąc, widziałeś kiedyś produkcyjny serwer MAC?
AlexV

3
@ imgx64 Zostało to naprawione 33 dni po twoim wpisie :) Zaktualizowałem moją odpowiedź, aby odzwierciedlić obecne źródła.
AlexV

2
Nie sądzę, aby argument użycia PHP_EOL dla wyjścia (!) Był poprawny. PHP_EOL jest po stronie serwera, podczas gdy dane wyjściowe są zwykle dla klienta (który używa różnych ograniczników końca linii). Przykład: Jeśli utworzysz wieloliniowy tekst wyjściowy w systemie Linux z PHP_EOL i wyślesz go do systemu Windows, nie będzie to prawidłowy separator kończący linię - będzie to zależeć od tego, jakie oprogramowanie klienckie wyświetli dane wyjściowe. Przeglądarki i niektóre edytory tekstu mogą to obsłużyć, ale jeśli przejrzysz tekst na przykład w Notatniku, wszystko będzie w jednym wierszu.
StanE

php -r "echo addcslashes(PHP_EOL, PHP_EOL), PHP_EOL;"dowiedzieć się.
Bob Stein,

81

Używasz, PHP_EOLkiedy chcesz nowej linii i chcesz być wieloplatformowy.

Może się tak zdarzyć, gdy piszesz pliki w systemie plików (dzienniki, eksport, inne).

Możesz go użyć, jeśli chcesz, aby wygenerowany HTML był czytelny. Więc możesz śledzić swoje <br />z PHP_EOL.

Użyłbyś go, jeśli korzystasz z php jako skryptu z crona i potrzebujesz czegoś wypisać i sformatować dla ekranu.

Możesz go użyć, jeśli tworzysz wiadomość e-mail, która wymagała sformatowania.


25
Podczas generowania HTML nie musisz używać niezależnych od platformy znaków nowej linii.
Rob

6
@Rob, Jeśli starsze wersje IE dały mi lepszą przeglądarkę źródeł, to Windows Notatnik mógłbym się z tobą zgodzić.
Zoredache

14
@Zoredache - HTML zostanie wygenerowany z nowymi wierszami odpowiednimi dla platformy, na której działa PHP, niekoniecznie odpowiednie dla platformy, z której uzyskujesz dostęp do stron.
Dominic Rodger

2
+1 za wzmiankę o budowie e-maila $header = "From: $from" . PHP_EOL; $header .= "Reply-To: $from" . PHP_EOL; $header .= "Return-Path: $from" . PHP_EOL;
Jakob Cosoroaba

49
PHP_EOLnie należy używać do rozdzielania nagłówków wiadomości e-mail. Zgodnie z instrukcją PHP Mail wiele dodatkowych nagłówków należy oddzielić za pomocą CRLF (\ r \ n).
Halil Özgür

19

PHP_EOL (ciąg) Prawidłowy symbol „End Of Line” dla tej platformy. Dostępne od PHP 4.3.10 i PHP 5.0.2

Tej stałej można użyć podczas odczytu lub zapisu plików tekstowych w systemie plików serwera.

Końcówki linii w większości przypadków nie mają znaczenia, ponieważ większość programów obsługuje pliki tekstowe bez względu na ich pochodzenie. Powinieneś być zgodny ze swoim kodem.

Jeśli zakończenia linii mają znaczenie, jawnie określ zakończenia linii zamiast używać stałej. Na przykład:

  • Nagłówki HTTP muszą być oddzielone przez\r\n
  • Pliki CSV powinny być używane \r\njako separator wierszy

5
źródło „Nagłówki HTTP muszą być ...”: ietf.org/rfc/rfc2616.txt rozdział 4 sekcja 1
Adrian Föder

2
Linie wiadomości SMTP muszą zostać zakończone przez\r\n
Bob Stein

12

Chciałbym wrzucić odpowiedź, która dotyczy „Kiedy nie należy jej używać”, ponieważ nie została jeszcze omówiona i mogę sobie wyobrazić, że jest używana na ślepo i nikt nie zauważy problemu, dopóki nie pojawi się problem. Niektóre z nich są nieco sprzeczne z niektórymi istniejącymi odpowiedziami.

Jeśli wpisywanie do strony internetowej w HTML, szczególnie tekstów w <textarea>, <pre>lub <code>prawdopodobnie zawsze chcesz używać \ni nie PHP_EOL.

Powodem tego jest fakt, że chociaż kod może działać dobrze na jednym serwerze (który jest platformą uniksową), jeśli zostanie wdrożony na hoście Windows (takim jak platforma Windows Azure), może on zmienić sposób wyświetlania stron w niektórych przeglądarkach (w szczególności Internet Explorer - niektóre wersje zobaczą zarówno \ n, jak i \ r).

Nie jestem pewien, czy jest to problem od czasu IE6, czy nie, więc może to być dość dyskusyjne, ale wydaje się warte wspomnienia, jeśli pomaga ludziom w szybkim myśleniu o kontekście. Mogą istnieć inne przypadki (takie jak ścisły XHTML), w których nagłe wyświetlanie \rna niektórych platformach może powodować problemy z wyjściem, i jestem pewien, że istnieją inne takie przypadki brzegowe.

Jak zauważył już ktoś, nie chciałbyś go używać do zwracania nagłówków HTTP - ponieważ powinny one zawsze postępować zgodnie z RFC na dowolnej platformie.

Nie użyłbym tego do czegoś takiego jak ograniczniki w plikach CSV (jak ktoś sugerował). Platforma, na której działa serwer, nie powinna określać zakończeń linii w generowanych lub pobieranych plikach.


10

Uważam, że PHP_EOL jest bardzo przydatny do obsługi plików, szczególnie jeśli piszesz wiele wierszy treści w pliku.

Na przykład masz długi ciąg, który chcesz podzielić na wiele linii podczas pisania do zwykłego pliku. Użycie \ r \ n może nie działać, więc po prostu wstaw PHP_EOL do skryptu, a wynik jest niesamowity.

Sprawdź ten prosty przykład poniżej:

<?php

$output = 'This is line 1' . PHP_EOL .
          'This is line 2' . PHP_EOL .
          'This is line 3';

$file = "filename.txt";

if (is_writable($file)) {
    // In our example we're opening $file in append mode.
    // The file pointer is at the bottom of the file hence
    // that's where $output will go when we fwrite() it.
    if (!$handle = fopen($file, 'a')) {
         echo "Cannot open file ($file)";
         exit;
    }
    // Write $output to our opened file.
    if (fwrite($handle, $output) === FALSE) {
        echo "Cannot write to file ($file)";
        exit;
    }
    echo "Success, content ($output) wrote to file ($file)";
    fclose($handle);
} else {
    echo "The file $file is not writable";
}
?>

3
\ n \ r nigdy nie zadziała, ponieważ sekwencja ma być \ r \ n </pedantry>
frak

10

Nie, PHP_EOL nie obsługuje problemów z liniami końcowymi, ponieważ system, w którym używasz tej stałej, nie jest tym samym systemem, do którego wysyłasz dane wyjściowe.

W ogóle nie polecam używania PHP_EOL. Korzystanie z Uniksa / Linuksa \ n, MacOS / OS X również zmienił się z \ r na \ n, a w systemie Windows wiele aplikacji (zwłaszcza przeglądarek) może również wyświetlać go poprawnie. W systemie Windows łatwo jest zmienić istniejący kod po stronie klienta, aby używać tylko \ n i nadal zachować zgodność wsteczną: wystarczy zmienić ogranicznik przycinania linii z \ r \ n na \ n i zawinąć go w funkcję trim () .


3
Byłoby miło wiedzieć, dlaczego moja odpowiedź jest odrzucona ... Szalona ... Przyjęta odpowiedź jest błędna , a moja poprawna. Ogólnie nie jest poprawne stwierdzenie, że PHP_EOL obsługuje ten problem. Można go (i należy) używać, jeśli WYŁĄCZNIE czyta lub pisze coś do / z tego samego systemu. Ale przez większość czasu PHP jest używane do wysyłania czegoś z powrotem do klienta (co najprawdopodobniej o tym myślał pytający). Ponownie: PHP_EOL jest czystą stałą po stronie serwera. NIE (i nie może) poprawnie obsługiwać podziałów po stronie klienta. Napisz komentarz i powiedz mi, jeśli uważasz, że napisałem coś złego.
StanE

3
+1 za robienie dobrego punktu na ziarnie. Myślę, że został utracony, ponieważ przeglądarki nie wyświetlają białych znaków w html, więc powszechnym zastosowaniem byłyby aplikacje konsolowe. I jak powiedziałeś, w takim przypadku zakończenie linii zostanie zinterpretowane dla środowiska wykonawczego, co ma sens w przypadku aplikacji konsolowych, ale nie aplikacji internetowych klient-serwer.
Jeff Puckett,

Cóż, odpowiedź tak naprawdę nie ma związku. Wspominasz o kompatybilności przeglądarki i wysyłaniu plików do innych systemów. Nowa linia jest istotna w wynikach tekstowych, więc przeglądarki nie są istotne. I w przeciwieństwie do twojego głównego punktu, te pliki tekstowe zwykle używane na tej samej platformie, na której zostały zapisane.
grantwparks

6

Definicja PHP_EOL jest taka, że ​​daje nowy znak systemu operacyjnego, nad którym pracujesz.

W praktyce prawie nigdy nie powinieneś tego potrzebować. Rozważ kilka przypadków:

  • Kiedy wysyłasz dane do sieci, naprawdę nie ma żadnej konwencji poza tym, że powinieneś być konsekwentny. Ponieważ większość serwerów jest Unixy, i tak będziesz chciał użyć „\ n”.

  • Jeśli wysyłasz dane do pliku, PHP_EOL może wydawać się dobrym pomysłem. Jednak możesz uzyskać podobny efekt, mając dosłownie nowy wiersz w swoim pliku, a to pomoże ci, jeśli próbujesz uruchomić niektóre pliki w formacie CRLF na Uniksie bez blokowania istniejących nowych linii (jako facet z systemem podwójnego rozruchu , Mogę powiedzieć, że wolę to drugie zachowanie)

PHP_EOL jest tak absurdalnie długi, że naprawdę nie warto go używać.


33
-1 dla „PHP_EOL jest tak absurdalnie długi”. To nie jest poprawny argument.
viam0Zah

1
Całkowicie się z Tobą zgadzam. Wdrażanie php na niczym innym niż * nix nie ma sensu. Zatem - nie ma sensu używać PHP_EOL lub DIRECTORY_SEPARATOR.
Stann

@Stann Czy możesz wyjaśnić swój punkt widzenia na temat „Nie ma sensu wdrażanie php na niczym innym niż * nix”?
Sajuuk,

2
@Sajuuk Wierzę, że można by to nazwać „sarkazmem”.
Félix Gagnon-Grenier

3

Jest jedno oczywiste miejsce, w którym może się przydać: gdy piszesz kod, który głównie używa ciągów pojedynczych cudzysłowów. Można argumentować, czy:

echo 'A $variable_literal that I have'.PHP_EOL.'looks better than'.PHP_EOL;  
echo 'this other $one'."\n";

Sztuka ma być konsekwentna. Problem z mieszaniem i dopasowywaniem „” i „” polega na tym, że kiedy dostajesz długie łańcuchy, tak naprawdę nie chcesz iść na polowanie na rodzaj użytego cytatu.

Jak w przypadku wszystkich rzeczy w życiu, zależy to od kontekstu.


3

Standardowa „nowa linia” w systemie DOS / Windows to CRLF (= \ r \ n), a nie LFCR (\ n \ r). Jeśli zastosujemy to drugie, może to wywołać pewne nieoczekiwane (a właściwie, w gruncie rzeczy, oczekiwane!: D) zachowania.

Obecnie prawie wszystkie (dobrze napisane) programy akceptują standard LF (\ n) UNIX dla kodu nowej linii, nawet demony nadawców poczty (RFC ustawia CRLF jako nową linię dla nagłówków i treści wiadomości).


2

Przydatne z error_log (), jeśli wyprowadzasz wiele wierszy.

Znalazłem wiele instrukcji debugowania, które wyglądają dziwnie na mojej instalacji Windows, ponieważ programiści założyli końcówki uniksowe podczas dzielenia ciągów.


2

Używam stałej PHP_EOL w niektórych skryptach wiersza poleceń, które musiałem napisać. Tworzę na lokalnym komputerze z systemem Windows, a następnie testuję na serwerze z systemem Linux. Używanie stałej oznaczało, że nie musiałem się martwić, że użyję poprawnego zakończenia linii dla każdej z różnych platform.


2

Mam witrynę, w której skrypt logowania zapisuje nowy wiersz tekstu do pliku tekstowego po akcji użytkownika, który może korzystać z dowolnego systemu operacyjnego.

Użycie PHP_EOL nie wydaje się w tym przypadku optymalne. Jeśli użytkownik korzysta z systemu Mac OS i zapisuje do pliku tekstowego, umieści \ n. Podczas otwierania pliku tekstowego na komputerze z systemem Windows nie jest wyświetlany podział linii. Z tego powodu używam zamiast tego „\ r \ n”, co działa podczas otwierania pliku w dowolnym systemie operacyjnym.


1

Piszesz kod, który używa głównie ciągów pojedynczych cudzysłowów.

echo 'A $variable_literal that I have'.PHP_EOL.'looks better than'.PHP_EOL;  
echo 'this other $one'."\n";

0

Korzystam z WebCalendar i odkryłem, że barfs Maca iCal podczas importowania wygenerowanego pliku ics, ponieważ koniec linii jest zapisany w xcal.php jako „\ r \ n”. Wszedłem i zamieniłem wszystkie wystąpienia na PHP_EOL, a teraz iCal jest szczęśliwy! Przetestowałem go również w systemie Vista, a program Outlook również mógł zaimportować plik, mimo że znak końca wiersza to „\ n”.


<late> Oznacza to, że aplikacja będzie działać nieprawidłowo po wdrożeniu na serwerze Windows. Jeśli chcesz \n, użyj tego jawnie.
duskwuff -inactive-

0

Kiedy jumi (wtyczka joomla dla PHP) kompiluje kod z jakiegoś powodu, usuwa wszystkie ukośniki odwrotne z kodu. Tak, że coś takiego się $csv_output .= "\n";staje$csv_output .= "n";

Bardzo irytujący błąd!

Zamiast tego użyj PHP_EOL, aby uzyskać oczekiwany wynik.


2
naprawdę NAPRAWDĘ mam nadzieję, że to problem z konfiguracją, którego jeszcze nie znalazłeś. nie korzystałem z Joomla, ale jakie to okropne zachowanie, jeśli tak naprawdę to działa!
jon_darkstar

0

W niektórych systemach użyteczne może być użycie tej stałej, ponieważ na przykład, gdy wysyłasz wiadomość e-mail, możesz użyć PHP_EOL, aby skrypt między systemami działał na większej liczbie systemów ... ale nawet jeśli jest to przydatne, możesz to znaleźć stały niezdefiniowany, nowoczesny hosting z najnowszym silnikiem php nie ma tego problemu, ale myślę, że dobrą rzeczą jest napisanie kodu, który ratuje tę sytuację:

<?php
  if (!defined('PHP_EOL')) {
    if (strtoupper(substr(PHP_OS,0,3) == 'WIN')) {
      define('PHP_EOL',"\r\n");
    } elseif (strtoupper(substr(PHP_OS,0,3) == 'MAC')) {
      define('PHP_EOL',"\r");
    } elseif (strtoupper(substr(PHP_OS,0,3) == 'DAR')) {
      define('PHP_EOL',"\n");
    } else {
      define('PHP_EOL',"\n");
    }
  }
?>

Możesz więc używać PHP_EOL bez problemów ... oczywiste, że PHP_EOL powinien być używany w skrypcie, który powinien działać na większej liczbie systemów jednocześnie, w przeciwnym razie możesz użyć \ n lub \ r lub \ r \ n ...

Uwaga: PHP_EOL może być

1) on Unix    LN    == \n
2) on Mac     CR    == \r
3) on Windows CR+LN == \r\n

Mam nadzieję, że ta odpowiedź pomoże.


0

Właśnie wystąpił ten problem podczas wysyłania do klienta Windows. Jasne, PHP_EOL jest po stronie serwera, ale większość danych wyjściowych z php jest przeznaczona dla klientów Windows. Więc muszę umieścić moje ustalenia tutaj dla następnej osoby.

A) echo „Mój tekst”. PHP_EOL; // Źle, ponieważ powoduje to \ n, a większość wersji notatnika systemu Windows wyświetla to w jednym wierszu, a większość programów księgowych systemu Windows nie może zaimportować tego rodzaju znaku końca linii.

B) echo „Mój tekst \ r \ n”; // Źle, ponieważ pojedyncze cytowane ciągi php nie interpretują \ r \ n

C) echo „Mój tekst \ r \ n”; // Tak, to działa! Wygląda poprawnie w notatniku i działa podczas importowania pliku do innego oprogramowania systemu Windows, takiego jak oprogramowanie do rozliczania i produkcji systemu Windows.


-2

Wolę używać \ n \ r. Jestem także w systemie Windows i \ n działa dobrze z mojego doświadczenia.

Ponieważ PHP_EOL nie działa z wyrażeniami regularnymi i są to najbardziej użyteczne sposoby radzenia sobie z tekstem, naprawdę nigdy go nie użyłem ani nie potrzebowałem.


12
Uważaj na kolejność
znaków

Nie używasz go, ale twoja strona może być otwarta przez każdego na dowolnym komputerze, więc może to być problem
Owaiz Yusufi
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.