什么时候使用PHP常量“ PHP_EOL”?


360

什么时候使用是个好主意PHP_EOL

我有时会在PHP的代码示例中看到这一点。这样可以处理DOS / Mac / Unix终端问题吗?


1
我认为在此页面上已投票的答案中有很多令人误解的建议。如果您在两个不同的平台上运行脚本,然后比较输出或生成的数据(日志文件,html页面,数据库记录等),则PHP_EOL将导致差异不匹配。在大多数情况下,这不是您想要的。
donquixote

Answers:


357

是的,PHP_EOL表面上是用于以跨平台兼容的方式查找换行符,因此它可以处理DOS / Unix问题。

请注意,PHP_EOL表示当前系统的结束符。例如,在类似Unix的系统上执行时,它将找不到Windows终端行。


9
编写命令行脚本时,应将其用作结束符吗?
Thomas Owens

5
@Andre:任何编写要由他人安装,使用和部署的应用程序的人如何?您是否建议这些都将其“受支持的平台”限制为* nix?
Cylindric

1
@Stann-您所了解的“大型项目”几乎不是最佳实践的决定因素,更不用说什么是有用的或无用的了。我维护一个“大项目”,该项目部分部署在多个主机上,包括某些Windows服务器。不要假设-常量不会损害任何东西,并且是编写与平台无关的代码的完全有效的方法。您相反的评论有些荒谬。
克里斯·贝克

5
不,我认为您的答案不正确。您在一个系统上生成代码,但是将输出发送到另一个系统。但是,PHP_EOL仅告诉您使用它的系统的行尾定界符。它不能保证您其他系统使用相同的定界符。请参阅下面的答案。
StanE

1
但请勿PHP_EOL用于从表单发布的数据。
纳比·卡兹

88

main/php.hPHP版本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"(在其他任何设备上)。在5.4.0RC8 之前的 PHP版本上,PHP_EOL:("\r"在MacOSX服务器上)可能存在第三个值。这是错误的,已于2012-03-01 修复错误为61193

正如其他人已经告诉您的那样,您可以PHP_EOL在需要统一换行符的任何类型的输出(这些值中的任何一个都是有效的,例如:HTML,XML,日志...)中使用。请记住,确定值的是服务器,而不是客户端。Windows访问者将从您的Unix服务器上获得价值,这有时对他们来说不方便。

我只想显示PHP_EOLPHP来源支持的可能值,因为此处尚未显示。


3
哇。PHP开发人员对此是错误的。正如您所提到的Wikipedia链接,Mac OS 9和以前的版本使用的是“ \ r”,而OS X则没有使用“ \ n”。有人应该提交错误报告...
imgx64

27
@ imgx64是的,但老实说,您是否见过生产型MAC服务器?
AlexV 2012年

3
@ imgx64您的帖子发布33天后,此问题已解决:)我已经更新了答案,以反映当前消息来源。
AlexV

2
我认为将PHP_EOL用于输出(!)的参数无效。PHP_EOL是服务器端的,而输出通常是客户端的(使用不同的行尾定界符)。示例:如果您在Linux系统上使用PHP_EOL创建多行纯文本输出,并将其发送到Windows系统,则该行将不是有效的行结束定界符-它取决于将显示输出的客户端软件。浏览器和某些文本编辑器可能会处理它,但是如果您在记事本中查看例如文本,则所有内容都将在一行中。
StanE 2015年

php -r "echo addcslashes(PHP_EOL, PHP_EOL), PHP_EOL;"找出答案。
鲍勃·斯坦

81

您可以使用PHP_EOL,当你想要一个新的生产线,和你想成为跨平台的。

这可能是在您将文件写入文件系统(日志,导出,其他)时。

如果希望生成的HTML可读,则可以使用它。因此,您可能会跟随<br />一个PHP_EOL

如果您正在运行cron中的php作为脚本,并且需要输出某些内容并将其格式化为屏幕格式,则可以使用它。

如果您要建立一封电子邮件以发送需要某种格式的电子邮件,则可以使用它。


25
生成HTML时无需使用平台无关的换行符。
罗布

6
@Rob,如果旧版本的IE给我提供了更好的页面源查看器,则我可能已同意Windows记事本。
Zoredache

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 2010年

49
PHP_EOL不应用于分隔电子邮件标题。根据PHP Mail手册,应使用CRLF(\ r \ n)分隔多个额外的标头。
HalilÖzgür10年

19

PHP_EOL(字符串)此平台的正确“行尾”符号。自PHP 4.3.10和PHP 5.0.2起可用

在服务器的文件系统上读取或写入文本文件时,可以使用此常数。

在大多数情况下,行尾并不重要,因为大多数软件都可以处理文本文件,而不管其来源如何。您应该与代码保持一致。

如果行尾很重要,请显式指定行尾,而不要使用常量。例如:

  • HTTP标头必须\r\n
  • CSV文件应该使用\r\n作为行分隔符

5
“ HTTP标头必须为...”的来源:ietf.org/rfc/rfc2616.txt第4章第1部分
AdrianFöder,2016年

2
SMTP消息行必须\r\n
Bob Stein'17

12

我想提出一个针对“何时使用它” 的答案,因为它尚未被涵盖,并且可以想象它被盲目使用了,直到下线才有人注意到这是一个问题。其中一些与某些现有答案有些矛盾。

如果以HTML格式输出到网页,尤其是in中的文本<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
\ n \ r永远不会起作用,因为该序列本来是\ r \ n </ pedantry>
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 '16

3
+1是针对谷物的好点子。我认为它已经丢失了,因为浏览器无法在html中呈现空格,因此通常用于控制台应用程序。就像您说的那样,在这种情况下,行尾将针对执行环境进行解释,这对于控制台应用程序有意义,但对于客户端-服务器Web应用程序则没有意义。
杰夫·普基特

好吧,答案并没有真正的关系。您提到了浏览器兼容性并将文件发送到其他系统。换行符与文本输出相关,因此浏览器不相关。出乎你的主要观点,这些文本文件通常消耗他们写在同一个平台上。
Grantwparks

6

PHP_EOL的定义是,它为您提供了正在使用的操作系统的换行符。

实际上,您几乎永远不需要它。考虑以下几种情况:

  • 当您输出到Web时,实际上没有任何约定,只是您应该保持一致。由于大多数服务器都是Unixy,因此无论如何您都希望使用“ \ n”。

  • 如果要输出到文件,则PHP_EOL似乎是一个好主意。但是,通过在文件中包含文字换行符,可以得到类似的效果,如果您尝试在Unix上运行某些CRLF格式的文件而又不破坏现有的换行符,那么这将为您提供帮助(例如,使用双启动系统的人,可以说我更喜欢后者的行为)

PHP_EOL太长了,以至于真的不值得使用它。


33
-1表示“ PHP_EOL太长了”。这不是有效的论据。
viam0Zah 2010年

1
我完全同意你的观点。除了* nix以外,在任何其他地方部署php毫无意义。因此-使用PHP_EOL或DIRECTORY_SEPARATOR没有意义。
斯坦

@Stann您能否解释一下您的观点:“在* nix以外的任何东西上部署php毫无意义”?
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

我有一个网站,在该网站上,用户可以使用任何操作系统执行操作后,日志记录脚本都会在文本文件中写入新行文本。

在这种情况下,使用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文件时使用barfs,因为行尾在xcal.php中被硬编码为“ \ r \ n”。我进去并用PHP_EOL替换了所有出现的内容,现在iCal很高兴!我还在Vista上进行了测试,即使行尾字符为“ \ n”,Outlook也能够导入文件。


<late>这意味着您的应用程序在Windows服务器上部署时将发生故障。如果需要\n,请显式使用。
黄昏

0

当jumi(PHP的joomla插件)​​出于某种原因编译您的代码时,它将删除代码中的所有反斜杠。这样的东西$csv_output .= "\n";变成$csv_output .= "n";

非常烦人的错误!

使用PHP_EOL来获得您想要的结果。


2
我真的很希望这是您尚未发现的配置问题。我还没有使用过joomla,但是如果那真的是怎么工作的,那真是太糟糕了!
jon_darkstar 2010年

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客户端的。因此,我必须在这里为下一个人放置我的发现。

A)回显“我的文字”。PHP_EOL; //不好,因为它仅输出\ n,并且大多数版本的Windows记事本都在一行上显示,大多数Windows记帐软件无法导入这种类型的行尾字符。

B)回显'我的文字\ r \ n'; //错误,因为单引号的PHP字符串不能解释\ r \ n

C)回显“我的文字\ r \ n”;//是的,它起作用了!在记事本中看起来正确,并且在将文件导入其他Windows软件(例如Windows记帐和Windows制造软件)时有效。


-2

我更喜欢使用\ n \ r。另外,我使用的是Windows系统,根据我的经验,\ n可以正常工作。

由于PHP_EOL不适用于正则表达式,而这些是处理文本的最有用的方法,因此我真的从未使用过它,也不需要使用它。


12
当心换行符,应该是\ r \ n(CR + LF):en.wikipedia.org/wiki/Newline
azkotoki 2011年

您没有使用它,但是您的站点可以由任何人在任何PC上打开,因此可能是个问题
Owaiz Yusufi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.