Когда я использую PHP-константу «PHP_EOL»?


360

Когда это хорошая идея для использования PHP_EOL?

Я иногда вижу это в примерах кода PHP. Это решает проблемы конечной линии DOS / Mac / Unix?


1
Я думаю, что в ответах на этой странице есть много вводящих в заблуждение советов. Если вы запускаете скрипт на двух разных платформах, затем сравниваете выходные или сгенерированные данные (файлы журналов, html-страницы, записи базы данных и т. Д.), Тогда PHP_EOL приведет к несоответствию в diff. В большинстве случаев это не то, что вы хотите.
Donquixote

Ответы:


357

Да, PHP_EOLякобы используется для поиска символа новой строки в кроссплатформенной совместимости, поэтому он решает проблемы DOS / Unix.

Обратите внимание, что PHP_EOL представляет символ конца строки для текущей системы. Например, он не найдет конечную строку Windows при выполнении в Unix-подобной системе.


9
Должен ли он использоваться в качестве символа конца строки при написании сценария командной строки?
Томас Оуэнс

5
@Andre: Как насчет тех, кто пишет приложения для установки, использования и развертывания другими? Вы предлагаете, чтобы все они ограничивали свои "поддерживаемые платформы" * nix?
Цилиндрический

1
@Stann - То, что делают "большие проекты", о которых вы знаете, вряд ли является решающим фактором для наилучшей практики, не говоря уже о том, что полезно или не полезно. Я поддерживаю «большой проект», который частично развернут на нескольких хостах, включая некоторые серверы Windows. Не думайте, что константы ничем не вредят и являются совершенно правильным способом написания кода, не зависящего от платформы. Ваши комментарии наоборот несколько абсурдны.
Крис Бейкер

5
Нет, я не думаю, что ваш ответ правильный. Вы генерируете код в одной системе, но отправляете вывод в другую систему. PHP_EOL, однако, говорит вам, что разделитель конца строки ТОЛЬКО для системы, где он используется. Это не гарантирует, что другая система использует тот же разделитель. Смотрите мой ответ ниже.
Стэн

1
но не используйте PHP_EOLдля данных, отправленных из формы.
Наби КАЗ

88

Начиная main/php.hс версии PHP 7.1.1 и версии 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

Как видите, PHP_EOLможет быть "\r\n"(на серверах Windows) или "\n"(на любом другом). В версиях PHP до 5.4.0RC8 было возможно третье значение для PHP_EOL: "\r"(на серверах MacOSX). Это было неправильно и было исправлено 2012-03-01 с ошибкой 61193 .

Как уже говорили другие, вы можете использовать PHP_EOLв любом виде вывода (где любое из этих значений допустимо - например, HTML, XML, журналы ...), где вы хотите объединенные переводы строк . Имейте в виду, что значение определяет сервер, а не клиент. Ваши посетители Windows получат выгоду от вашего Unix-сервера, что иногда неудобно для них.

Я просто хотел показать возможные значения, PHP_EOLподдерживаемые источниками PHP, так как он еще не был показан здесь ...


3
Ух ты. Разработчики PHP просто ошибаются по этому поводу. В качестве ссылки на Википедию вы упоминаете, что Mac OS 9 и ранее использовала «\ r», но не OS X, которая использует «\ n». Кто-то должен подать отчет об ошибке ...
imgx64

27
@ imgx64 Да, но если честно, вы когда-нибудь видели рабочий сервер MAC?
AlexV

3
@ imgx64 Это было исправлено через 33 дня после вашего сообщения :) Я обновил свой ответ, чтобы отразить текущие источники.
AlexV

2
Я не думаю, что аргумент для использования PHP_EOL для вывода (!) Является действительным. PHP_EOL на стороне сервера, в то время как вывод обычно для клиента (который использует разные разделители конца строки). Пример: если вы создадите многострочный вывод простого текста в системе linux с помощью PHP_EOL и отправите его в систему Windows, это не будет допустимым разделителем конца строки - это будет зависеть от того, какое клиентское программное обеспечение будет отображать вывод. Браузеры и некоторые текстовые редакторы могут справиться с этим, но если вы просматриваете текст, например, в Блокноте, все будет в одной строке.
Стэн

php -r "echo addcslashes(PHP_EOL, PHP_EOL), PHP_EOL;"выяснить.
Боб Стейн

82

Вы используете, PHP_EOLкогда вы хотите новую линию, и вы хотите быть кроссплатформенным.

Это может быть при записи файлов в файловую систему (журналы, экспорт, другое).

Вы можете использовать его, если хотите, чтобы сгенерированный HTML-код был читабельным. Таким образом, вы можете следовать <br />с PHP_EOL.

Вы бы использовали его, если вы запускаете php как скрипт из cron и вам нужно что-то вывести и отформатировать для экрана.

Вы можете использовать его, если создаете электронное письмо для отправки, которое требует некоторого форматирования.


25
Вам не нужно использовать независимую от платформы новую строку при создании HTML.
Роб

6
@Rob, Если бы более старые версии IE давали мне лучшее средство просмотра исходного кода, чем блокнот Windows, я бы мог с вами согласиться.
Зоредаче

14
@Zoredache - HTML будет генерироваться с символами новой строки, подходящими для платформы, на которой работает PHP, не обязательно для платформы, с которой вы обращаетесь к страницам.
Доминик Роджер

2
+1 за упоминание здания электронной почты $header = "From: $from" . PHP_EOL; $header .= "Reply-To: $from" . PHP_EOL; $header .= "Return-Path: $from" . PHP_EOL;
Jakob Cosoroaba

49
PHP_EOLне должен использоваться для разделения заголовков электронной почты. Согласно руководству PHP Mail , несколько дополнительных заголовков должны быть разделены CRLF (\ r \ n).
Халил Озгюр

19

PHP_EOL (string) Правильный символ «Конец строки» для этой платформы. Доступно с PHP 4.3.10 и PHP 5.0.2

Вы можете использовать эту константу при чтении или записи текстовых файлов в файловой системе сервера.

Окончания строк не имеют значения в большинстве случаев, так как большинство программных средств способны обрабатывать текстовые файлы независимо от их происхождения. Вы должны соответствовать вашему коду.

Если окончания строк имеют значение, явно указывайте окончания строк вместо использования константы. Например:

  • Заголовки HTTP должны быть разделены\r\n
  • CSV-файлы должны использовать в \r\nкачестве разделителя строк

5
источник для «HTTP-заголовков должен быть ...»: ietf.org/rfc/rfc2616.txt глава 4, раздел 1
Адриан Фодер,

2
Строки SMTP- сообщений должны быть \r\n
Боб Стейн

12

Я хотел бы добавить ответ, который касается «Когда его не использовать», так как он еще не был рассмотрен, и могу представить, что его используют вслепую, и никто не замечает, что есть проблема до тех пор, пока не произойдет. Отчасти это несколько противоречит некоторым из существующих ответов.

Если вы выводите на веб-страницу в HTML, в частности, текст <textarea>, <pre>или <code>вы, вероятно, всегда хотите использовать, \nа не PHP_EOL.

Причина этого заключается в том, что, хотя код может работать хорошо на одном сервере, который является платформой, подобной Unix, при развертывании на хосте Windows (например, на платформе Windows Azure) он может изменить способ отображения страниц в некоторых браузерах. (в частности, Internet Explorer - некоторые версии которого будут видеть как \ n, так и \ r).

Я не уверен, если это все еще проблема с IE6 или нет, так что это может быть довольно спорным, но, кажется, стоит упомянуть, если это помогает людям подсказывать думать о контексте. Могут быть и другие случаи (например, строгий XHTML), в которых внезапный вывод \rна некоторых платформах может вызвать проблемы с выводом, и я уверен, что есть и другие крайние случаи, подобные этому.

Как уже было отмечено кем-то, вы не захотите использовать его при возврате заголовков HTTP - так как они всегда должны следовать RFC на любой платформе.

Я бы не стал использовать его для обозначения разделителей в файлах CSV (как кто-то предложил). Платформа, на которой работает сервер, не должна определять окончания строк в генерируемых или потребляемых файлах.


10

Я нашел PHP_EOL очень полезным для обработки файлов, особенно если вы пишете несколько строк контента в файл.

Например, у вас есть длинная строка, которую вы хотите разбить на несколько строк при записи в простой файл. Использование \ r \ n может не сработать, поэтому просто вставьте PHP_EOL в ваш скрипт, и результат будет потрясающим.

Проверьте этот простой пример ниже:

<?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
\ п \ г никогда не будет работать , как последовательность предназначается , чтобы быть \ г \ п </ педантизм>
Frak

10

Нет, PHP_EOL не обрабатывает проблемы с конечной линией, потому что система, в которой вы используете эту константу, не та же система, в которую вы отправляете выходные данные.

Я бы не рекомендовал использовать PHP_EOL вообще. В Unix / Linux используется \ n, MacOS / OS X также изменена с \ r на \ n, и в Windows многие приложения (особенно браузеры) также могут отображать его правильно. В Windows также легко изменить существующий код на стороне клиента, чтобы использовать только \ n, и при этом поддерживать обратную совместимость: просто измените разделитель для обрезки строки с \ r \ n на \ n и оберните его в функции trim () ,


3
Было бы приятно узнать, почему мой ответ опровергнут ... Сумасшедший ... Принятый ответ неправильный , а мой правильный. Как правило, неверно говорить, что PHP_EOL решает проблему. Он может (и должен) использоваться, если ЧТЕНИЕ или запись ТОЛЬКО чего-либо в одну и ту же систему. Но большую часть времени PHP используется для отправки чего-либо обратно клиенту (что, скорее всего, и задумал спрашивающий). Опять же: PHP_EOL является чистой серверной константой. Он НЕ (и не может) правильно обрабатывать разрывы строк на стороне клиента. Пожалуйста, напишите комментарий и скажите мне, если вы считаете, что я написал что-то не так.
StanE

3
+1 за хорошую точку против зерна. Я думаю, что это потеряно, потому что браузеры не отображают пробелы в html, поэтому обычное использование будет для консольных приложений. И, как вы сказали, в этом случае конец строки будет интерпретироваться для исполняющей среды, что имеет смысл для консольных приложений, но не для веб-приложений клиент-сервер.
Джефф Пакетт

Ну, ответ на самом деле не имеет отношения. Вы упоминаете совместимость браузера и отправку файлов в другие системы. Новая строка актуальна при выводе текста, поэтому браузеры не актуальны. И в отличие от вашей основной точки, эти текстовые файлы являются обычно потребляются на той же платформе , они написаны.
grantwparks

6

Определение PHP_EOL заключается в том, что он дает вам символ новой строки операционной системы, над которой вы работаете.

На практике вам это почти никогда не нужно. Рассмотрим несколько случаев:

  • Когда вы выводите в Интернет, на самом деле не существует никаких соглашений, кроме того, что вы должны быть последовательными. Поскольку большинство серверов Unixy, вы все равно захотите использовать «\ n».

  • Если вы выводите в файл, PHP_EOL может показаться хорошей идеей. Тем не менее, вы можете получить аналогичный эффект, имея буквальный символ новой строки внутри вашего файла, и это поможет вам, если вы попытаетесь запустить некоторые файлы в формате CRLF в Unix, не забивая существующие символы новой строки (как парень с двойной загрузкой системы). Могу сказать, что предпочитаю последнее поведение)

PHP_EOL настолько смехотворно длинен, что его действительно не стоит использовать.


33
-1 для "PHP_EOL так смешно долго". Это не правильный аргумент.
viam0Zah

1
Я полностью согласен с тобой. Нет смысла развертывать php ни на чем, кроме * nix. Таким образом - нет смысла использовать PHP_EOL или DIRECTORY_SEPARATOR.
Стэнн

@Stann Можете ли вы объяснить свою мысль о том, что "нет никакого смысла развертывать php ни на чем, кроме * nix"?
Sajuuk

2
@Sajuuk Я считаю, что это будет называться "сарказм".
Феликс Ганьон-Гренье

3

Есть одно очевидное место, где это может быть полезно: когда вы пишете код, который преимущественно использует строки в одинарных кавычках. Его спорно, как в том, что:

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

Искусство это быть последовательным. Проблема со смешиванием и соответствием '' и "" состоит в том, что когда вы получаете длинные строки, вам не нужно охотиться за тем, какой тип цитаты вы использовали.

Как и все вещи в жизни, это зависит от контекста.


3

DOS / Windows стандартная "новая строка" - это CRLF (= \ r \ n), а не LFCR (\ n \ r). Если мы добавим последнее, это может привести к неожиданному (ну, на самом деле, ожидаемому!: D) поведению.

В настоящее время почти все (хорошо написанные) программы принимают стандарт UNIX LF (\ n) для кода новой строки, даже демонов отправителей почты (RFC устанавливает CRLF в качестве новой строки для заголовков и тела сообщения).


2

Удобно с error_log (), если вы выводите несколько строк.

Я обнаружил, что многие операторы отладки выглядят странно на моей установке Windows, так как разработчики предполагали окончания в Unix, разбивая строки


2

Я использую константу PHP_EOL в некоторых сценариях командной строки, которые мне пришлось написать. Я разрабатываю на своей локальной машине Windows, а затем тестирую на сервере Linux. Использование константы означало, что мне не нужно беспокоиться об использовании правильного окончания строки для каждой из разных платформ.


2

У меня есть сайт, где logging-скрипт записывает новую строку текста в текстовый файл после действия пользователя, который может использовать любую ОС.

Использование PHP_EOL не кажется оптимальным в этом случае. Если пользователь работает в Mac OS и пишет в текстовый файл, он поставит \ n. При открытии текстового файла на компьютере с Windows он не показывает разрыв строки. По этой причине я использую "\ r \ n" вместо этого, который работает при открытии файла в любой ОС.


1

Вы пишете код, который преимущественно использует одинарные кавычки.

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

0

Я использую WebCalendar и обнаружил, что Mac iCal препятствует импорту сгенерированного файла ics, потому что конец строки жестко закодирован в xcal.php как "\ r \ n". Я зашел и заменил все вхождения на PHP_EOL, и теперь iCal счастлив! Я также протестировал его в Vista, и Outlook также смог импортировать файл, хотя символ конца строки - «\ n».


<late> Это означает, что ваше приложение будет работать неправильно при развертывании на сервере Windows. Если хотите \n, используйте это явно.
сумерки -неактив-

0

Когда jumi (плагин joomla для PHP) по какой-то причине компилирует ваш код, он удаляет все обратные косые черты из вашего кода. Такой что-то вроде $csv_output .= "\n";становится$csv_output .= "n";

Очень раздражающая ошибка!

Вместо этого используйте PHP_EOL, чтобы получить желаемый результат.


2
я действительно ДЕЙСТВИТЕЛЬНО надеюсь, что это проблема конфигурации, которую вы еще не нашли. Я не использовал Joomla, но какое ужасное поведение, если это действительно так работает!
jon_darkstar

0

В некоторых системах может быть полезно использовать эту константу, потому что, например, если вы отправляете электронное письмо, вы можете использовать PHP_EOL, чтобы межсистемный скрипт работал на большем количестве систем ... но даже если иногда это полезно, вы можете найти это Постоянный неопределенный, современный хостинг с последним движком php не имеет этой проблемы, но я думаю, что хорошо бы написать немного кода, который спасет эту ситуацию:

<?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");
    }
  }
?>

Таким образом, вы можете использовать PHP_EOL без проблем ... очевидно, что PHP_EOL должен использоваться в сценарии, который должен работать на нескольких системах одновременно, в противном случае вы можете использовать \ n или \ r или \ r \ n ...

Примечание: PHP_EOL может быть

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

Надеюсь, этот ответ поможет.


0

Я только что столкнулся с этой проблемой при выводе на клиент Windows. Конечно, PHP_EOL предназначен для серверной части, но большая часть содержимого, выводимого из php, предназначена для клиентов Windows. Поэтому я должен разместить свои выводы здесь для следующего человека.

А) эхо «Мой текст». PHP_EOL; // Плохо, потому что это просто выводит \ n, и большинство версий Windows Notepad отображают это в одной строке, и большинство программ учета Windows не может импортировать этот тип символа конца строки.

B) повторить «Мой текст \ r \ n»; // Плохо, потому что php-строки в одинарных кавычках не интерпретируют \ r \ n

В) эхо "Мой текст \ r \ n"; // Да, это работает! В блокноте выглядит правильно и работает при импорте файла в другое программное обеспечение Windows, такое как Windows Accounting и Windows Manufacturing.


-2

Я предпочитаю использовать \ n \ r. Также я нахожусь в системе Windows, и \ n работает просто отлично в моем опыте.

Поскольку PHP_EOL не работает с регулярными выражениями, и это наиболее полезный способ работы с текстом, я действительно никогда не использовал его или не нуждался в этом.


12
Остерегайтесь порядка символов новой строки, он должен быть \ r \ n (CR + LF): en.wikipedia.org/wiki/Newline
azkotoki

Вы не используете его, но ваш сайт может быть открыт любым пользователем на любом компьютере, поэтому это может быть проблемой
Owaiz Yusufi
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.