什么时候使用 PHP 常量“PHP_EOL”?
Posted
技术标签:
【中文标题】什么时候使用 PHP 常量“PHP_EOL”?【英文标题】:When do I use the PHP constant "PHP_EOL"? 【发布时间】:2010-09-12 19:34:24 【问题描述】:什么时候使用php_EOL
比较好?
我有时会在 PHP 的代码示例中看到这一点。这能处理 DOS/Mac/Unix 端行问题吗?
【问题讨论】:
我认为此页面上的赞成答案中有很多误导性建议。如果您在两个不同的平台上运行脚本,然后比较输出或生成的数据(日志文件、html 页面、数据库记录等),那么 PHP_EOL 将导致差异不匹配。在大多数情况下,这不是您想要的。 【参考方案1】:我刚刚在输出到 Windows 客户端时遇到了这个问题。当然,PHP_EOL 用于服务器端,但 php 的大多数内容输出是用于 Windows 客户端的。所以我必须把我的发现放在这里给下一个人。
A) 回显“我的文本”。 PHP_EOL; // 不好,因为这只是输出 \n 并且大多数版本的 windows 记事本都显示在一行上,并且大多数 windows 会计软件无法导入这种类型的行尾字符。
B) echo '我的文字\r\n'; //不好,因为单引号 php 字符串不解释 \r\n
C) 回显“我的文本\r\n”; // 是的,它有效!在记事本中看起来正确,并且在将文件导入其他 Windows 软件(如 Windows 会计和 Windows 制造软件)时可以正常工作。
【讨论】:
【参考方案2】:在某些系统上使用此常量可能很有用,因为例如,如果您正在发送电子邮件,则可以使用 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
希望这个答案有所帮助。
【讨论】:
【参考方案3】:来自 PHP 7.1.1 和 5.6.30 版本的main/php.h
:
#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 年 3 月 1 日用bug 61193 修复。
正如其他人已经告诉您的那样,您可以在任何类型的输出中使用PHP_EOL
(其中任何这些值都是有效的 - 例如:HTML、XML、日志...)统一newlines。请记住,确定值的是服务器,而不是客户端。您的 Windows 访问者会从您的 Unix 服务器获得价值,这有时对他们来说很不方便。
我只是想显示由 PHP 源支持的 PHP_EOL
的可能值,因为它还没有在这里显示...
【讨论】:
哇。 PHP 开发人员对此是错误的。正如您提到的***链接,Mac OS 9 及之前使用“\r”,但不是使用“\n”的 OS X。有人应该提交错误报告... @imgx64 是的,也许,但老实说,你见过生产 MAC 服务器吗? @imgx64 在您发帖 33 天后已修复 :) 我已更新我的答案以反映当前来源。 我不认为使用 PHP_EOL 输出的论点(!)是有效的。 PHP_EOL 是服务器端的,而输出通常用于客户端(使用不同的行结束分隔符)。示例:如果您使用 PHP_EOL 在 linux 系统上创建多行纯文本输出并将其发送到 Windows 系统,则它将不是有效的行尾分隔符 - 这取决于将显示输出的客户端软件。浏览器和一些文本编辑器可能会处理它,但如果您在记事本中查看文本,所有内容都将在一行中。php -r "echo addcslashes(PHP_EOL, PHP_EOL), PHP_EOL;"
找出答案。【参考方案4】:
是的,PHP_EOL
表面上用于以跨平台兼容的方式查找换行符,因此它可以处理 DOS/Unix 问题。
注意PHP_EOL 代表当前 系统的结束符。例如,在类 unix 系统上执行时,它不会找到 Windows 结束行。
【讨论】:
写命令行脚本时是否应该作为行尾符? @Andre:编写应用程序以供他人安装、使用和部署的人怎么样?您是否建议这些都应将其“支持的平台”限制为 *nix? @Stanni - 你所知道的“大项目”所做的几乎不是最佳实践的决定因素,更不用说什么有用或没用了。我维护一个“大项目”,部分部署在多个主机上,包括一些 Windows 服务器。不要假设 - 常量不会伤害任何东西,并且是编写平台中立代码的一种完全有效的方式。相反,你的 cmets 有点荒谬。 不,我认为您的回答不正确。您在一个系统上生成代码,但将输出发送到另一个系统。但是,PHP_EOL 只告诉您使用它的系统的行尾分隔符。它不保证其他系统使用相同的分隔符。请参阅下面的答案。 但不要将PHP_EOL
用于从表单发布的数据。【参考方案5】:
当你想要一个新行并且你想要跨平台时,你使用PHP_EOL
。
这可能是当您将文件写入文件系统(日志、导出、其他)时。
如果您希望生成的 HTML 可读,可以使用它。因此,您可以使用PHP_EOL
关注您的<br />
。
如果您从 cron 将 php 作为脚本运行并且需要输出一些内容并将其格式化为屏幕,则可以使用它。
如果您正在构建一封电子邮件以发送需要一些格式的邮件,则可以使用它。
【讨论】:
生成 HTML 时不需要使用与平台无关的换行符。 @Rob,如果旧版本的 IE 给了我更好的页面源代码查看器,那么我可能会同意你的看法。 @Zoredache - HTML 将使用适合 PHP 运行平台的换行符生成,不一定适合您访问页面的平台。 +1 用于提及电子邮件建设$header = "From: $from" . PHP_EOL; $header .= "Reply-To: $from" . PHP_EOL; $header .= "Return-Path: $from" . PHP_EOL;
PHP_EOL
不应用于分隔电子邮件标头。 根据PHP Mail 手册,应使用 CRLF (\r\n) 分隔多个额外标头。 【参考方案6】:
不,PHP_EOL 不处理 endline 问题,因为您使用该常量的系统与您将输出发送到的系统不同。
我根本不建议使用 PHP_EOL。 Unix/Linux 使用 \n,MacOS / OS X 也从 \r 更改为 \n,在 Windows 上,许多应用程序(尤其是浏览器)也可以正确显示它。在 Windows 上,将现有的客户端代码更改为仅使用 \n 并且仍然保持向后兼容性也很容易:只需将行修剪的分隔符从 \r\n 更改为 \n 并将其包装在类似 trim() 的函数中.
【讨论】:
很高兴知道为什么我的答案被否决...疯狂...接受的答案是错误,而我的答案是正确的。说 PHP_EOL 处理这个问题通常是不正确的。如果仅从 same 系统读取或写入某些内容,则可以(并且应该)使用它。但大多数时候 PHP 用于将某些内容发送回客户端(这很可能是提问者的想法)。再说一遍:PHP_EOL 是一个纯服务器端常量。它不能(也不能)正确处理客户端换行符。如果您认为我写错了,请写评论并告诉我。 +1 表示反对谷物。我认为它丢失了,因为浏览器不会在 html 中呈现空格,所以常见的用途是控制台应用程序。正如您所说,在这种情况下,行尾将被解释为执行环境,这对控制台应用程序有意义,但对客户端-服务器 Web 应用程序没有意义。 嗯,答案并不真正相关。您提到浏览器兼容性并将文件发送到其他系统。换行符与文本输出相关,因此浏览器不相关。与您的主要观点相反,这些文本文件通常在它们编写的同一平台上使用。【参考方案7】:我有一个站点,其中的日志记录脚本在用户执行操作后将新的一行文本写入文本文件,用户可以使用任何操作系统。
在这种情况下,使用 PHP_EOL 似乎不是最佳选择。如果用户在 Mac OS 上并写入文本文件,它将放置 \n。在 Windows 计算机上打开文本文件时,它不显示换行符。出于这个原因,我使用“\r\n”代替它在任何操作系统上打开文件时都有效。
【讨论】:
【参考方案8】:我发现 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";
?>
【讨论】:
\n\r 将永远不会工作,因为序列应该是 \r\n 【参考方案9】:我想提供一个解决“当不使用它”的答案,因为它还没有被覆盖并且可以想象它被盲目使用并且没有人注意到有一个问题,直到后来。其中一些与现有的一些答案有些矛盾。
如果以 HTML 格式输出到网页,尤其是 <textarea>
、<pre>
或 <code>
中的文本,您可能总是希望使用 \n
而不是 PHP_EOL
。
这样做的原因是,虽然代码可能在一台服务器上运行良好 - 这恰好是一个类似 Unix 的平台 - 如果部署在 Windows 主机(如 Windows Azure 平台)上,那么它可能会改变页面的显示方式在某些浏览器中(特别是 Internet Explorer - 某些版本会同时看到 \n 和 \r)。
我不确定自 IE6 以来这是否仍然是一个问题,所以它可能相当没有实际意义,但如果它有助于人们提示考虑上下文,似乎值得一提。可能还有其他情况(例如严格的 XHTML)在某些平台上突然输出 \r
可能会导致输出出现问题,我相信还有其他类似的边缘情况。
正如某人已经指出的那样,您不会希望在返回 HTTP 标头时使用它 - 因为它们应该始终遵循任何平台上的 RFC。
我不会将它用于 CSV 文件的分隔符之类的东西(正如有人建议的那样)。运行服务器的平台不应确定生成或使用的文件中的行结尾。
【讨论】:
【参考方案10】:您正在编写主要使用单引号字符串的代码。
echo 'A $variable_literal that I have'.PHP_EOL.'looks better than'.PHP_EOL;
echo 'this other $one'."\n";
【讨论】:
【参考方案11】:PHP_EOL(字符串) 此平台的正确“行尾”符号。 自 PHP 4.3.10 和 PHP 5.0.2 起可用
当您在服务器的文件系统上读取或写入文本文件时,您可以使用此常量。
在大多数情况下,行尾无关紧要,因为大多数软件都能够处理文本文件,无论其来源如何。您应该与您的代码保持一致。
如果行尾很重要,请明确指定行尾而不是使用常量。例如:
HTTP 标头必须以\r\n
分隔
CSV 文件应该使用\r\n
作为行分隔符
【讨论】:
“HTTP 标头必须是...”的来源:ietf.org/rfc/rfc2616.txt 第 4 章第 1 节 SMTP 消息行必须由\r\n
终止【参考方案12】:
DOS/Windows 标准“换行符”是 CRLF (= \r\n) 而不是 LFCR (\n\r)。如果我们把后者放在后面,它可能会产生一些意想不到的(嗯,事实上,有点预期!:D)行为。
现在几乎所有(编写良好的)程序都接受 UNIX 标准 LF (\n) 换行代码,甚至邮件发送者守护程序(RFC 将 CRLF 设置为 newline 用于标头和邮件正文)。
【讨论】:
【参考方案13】:当 jumi(PHP 的 joomla 插件)出于某种原因编译您的代码时,它会从您的代码中删除所有反斜杠。这样$csv_output .= "\n";
这样的东西就会变成$csv_output .= "n";
非常烦人的错误!
改用 PHP_EOL 来获得你想要的结果。
【讨论】:
我真的很希望这是您尚未发现的配置问题。我没有使用过 joomla,但如果它真的是这样工作的,那是多么可怕的行为!【参考方案14】:在一个明显的地方它可能有用:当您编写主要使用单引号字符串的代码时。是否有争议:
echo 'A $variable_literal that I have'.PHP_EOL.'looks better than'.PHP_EOL;
echo 'this other $one'."\n";
它的艺术是保持一致。混合匹配 '' 和 "" 的问题在于,当你得到长字符串时,你真的不想去寻找你使用的引用类型。
与生活中的所有事物一样,这取决于上下文。
【讨论】:
【参考方案15】:我更喜欢使用\n\r。另外,我在 Windows 系统上,\n 根据我的经验工作得很好。
由于 PHP_EOL 不适用于正则表达式,而这些是处理文本最有用的方式,所以我真的从未使用过或不需要。
【讨论】:
注意换行符的顺序,它应该是 \r\n (CR+LF): en.wikipedia.org/wiki/Newline 你不使用它,但你的网站可以被任何人在任何电脑上打开,所以这可能是个问题【参考方案16】:我正在使用 WebCalendar,发现 Mac iCal 在导入生成的 ics 文件时会出错,因为行尾在 xcal.php 中被硬编码为“\r\n”。我进去并用 PHP_EOL 替换了所有出现的地方,现在 iCal 很高兴! 我还在 Vista 上对其进行了测试,Outlook 也能够导入文件,即使行尾字符是“\n”。
【讨论】:
\n
,请明确使用它。我在必须编写的一些命令行脚本中使用 PHP_EOL 常量。我在本地 Windows 机器上开发,然后在 Linux 服务器上进行测试。使用常量意味着我不必担心为每个不同的平台使用正确的行尾。
【讨论】:
【参考方案18】:如果要输出多行,则可以使用 error_log()。
我发现很多调试语句在我的 Windows 安装中看起来很奇怪,因为开发人员在分解字符串时假定了 unix 结尾。
【讨论】:
【参考方案19】:PHP_EOL 的定义是它为您提供您正在使用的操作系统的换行符。
在实践中,您几乎不需要这个。考虑几个案例:
当您输出到网络时,除了您应该保持一致之外,实际上并没有任何约定。由于大多数服务器都是 Unixy,所以无论如何您都需要使用“\n”。
如果要输出到文件,PHP_EOL 似乎是个好主意。但是,您可以通过在文件中添加文字换行符来获得类似的效果,如果您尝试在 Unix 上运行一些 CRLF 格式的文件而不破坏现有的换行符(作为具有双引导系统的人),这将帮助您,我可以说我更喜欢后一种行为)
PHP_EOL 太长了,真的不值得使用。
【讨论】:
-1 表示“PHP_EOL 太长了”。这不是一个有效的论点。 我完全同意你的看法。在除 *nix 之外的任何东西上部署 php 都没有任何意义。因此 - 使用 PHP_EOL 或 DIRECTORY_SEPARATOR 毫无意义。 @Stann 你能解释一下你关于“除了 *nix 以外的任何地方部署 php 没有任何意义”的观点吗? @Sajuuk 我相信这会被称为“讽刺”。以上是关于什么时候使用 PHP 常量“PHP_EOL”?的主要内容,如果未能解决你的问题,请参考以下文章