为什么PHP Heredoc无法保留换行符?

Chr*_*sJJ 4 php-5.6

通过文档

Heredoc文本的行为就像带双引号的字符串,没有双引号。

此代码

<?php
echo "dc:<"."


".">";
echo "hd:<".<<<EOD


EOD
.">";
Run Code Online (Sandbox Code Playgroud)

应该输出:

dc:<


>hd:<


>
Run Code Online (Sandbox Code Playgroud)

但是,而是(在Windows的PHP V5.6.13上)它输出:

dc:<


>hd:<
>
Run Code Online (Sandbox Code Playgroud)

这是怎么回事?

Kod*_*son 5

我对此进行了实验,我认为我可以做出有根据的猜测。

在双引号字符串部分中,您有3条换行符:一条从第2行到第3行,一条从第3行到第4行,另一条从第4行到第5行。

在Heredoc部分中,您只有一个换行符。我认为Heredoc部分从第一个EOD令牌之后的行开始,到最后一个EOD令牌之前的行结束。因此,在您的heredoc中,只有7行到8行中的一个换行符,您可以在输出中看到它(在<>末尾之间的换行符)。如果将更多换行符添加到heredoc部分,则将在输出中看到它们。

希望这将有助于说明:

<?php
echo "dc:<"."          <-- first newline
                       <-- second newline
                       <-- third newline
".">";
echo "hd:<".<<<EOD     <-- heredoc starts after this part
                       <-- only one newline here
                       <-- heredoc ends here so this newline doesn't count
EOD
.">";
Run Code Online (Sandbox Code Playgroud)


针对您的评论:

“在Heredoc部分,您只有一个换行符。” 我有三个

是的,但是正如我已经说过的,我认为第一和最后一个换行符将被忽略。

“我认为Heredoc部分从第一个EOD令牌之后的行开始,到最后一个EOD令牌之前的行结束。”否。请参阅我发布的doc引用。

查看您链接到的文档中的以下文本(强调我的意思):

分隔字符串的第三种方法是heredoc语法:<<<。在此运算符之后,提供了一个标识符,然后提供了换行符。字符串本身跟随,然后再次输入相同的标识符以关闭引号。

注意,它说字符串本身在换行符之后。我相信,这证明了我的断言,因为它是Heredoc构造的一部分,因此省略了第一条换行符。诚然,这只能解释第一个换行符。但是我相信,出于同样的原因,最后的换行符也将被忽略。

“如果将更多换行符添加到heredoc部分,那么您将在输出中看到它们。” 是的,但是我的输出中换行符数量错误。

引用是:“ Heredoc文本的行为就像带双引号的字符串,没有双引号。”

我认为,如果您的双引号字符串部分的结构如下:

<?php
echo 'dc:<'.
"
"
.'>';
echo "hd:<".<<<EOD


EOD
.">";
Run Code Online (Sandbox Code Playgroud)

然后,它将按照您的期望工作。换句话说,heredoc的工作原理与不带双引号的双引号字符串相同。试试吧。