最佳实践:在PHP中使用长的多行字符串吗?


177

注意:很抱歉,如果这是一个非常简单的问题,但是我对代码的格式有些强迫。

我有一个类,该类具有返回字符串的函数,该字符串将构成电子邮件的正文。我希望此文本经过格式化,以便它在电子邮件中看起来很正确,而且也不会使我的代码显得时髦。这就是我的意思:

class Something
{
    public function getEmailText($vars)
    {
        $text = 'Hello ' . $vars->name . ",

The second line starts two lines below.

I also don't want any spaces before the new line, so it's butted up against the left side of the screen.";
        return $text;
    }
}

但也可以写成:

public function getEmailText($vars)
{
    $text = "Hello {$vars->name},\n\rThe second line starts two lines below.\n\rI also don't want any spaces before the new line, so it's butted up against the left side of the screen.";
    return $text;
}

但是换行和退货有什么关系呢?有什么不同?是\n\n相当于\r\r\n\r?在行与行之间创建行距时应该使用哪个?

然后是输出缓冲和heredoc语法的选项。

您如何处理在对象中使用长的多行字符串?


3
我一直认为\ n是Unix中的换行符\ r是OS / X之前的MacOS上的换行符,而\ r \ n是Windows上的换行符。另外,考虑到这将是显示在电子邮件中的字符串,因此您将要确保以哪种方式正确显示在大多数命令邮件客户端上。提示:在某些情况下,Outlook会删除多余的换行符,因此您将永远无法获得期望的结果。
肯尼·德罗布纳克

1
不知道这是否很重要,但是最初两个“换行”字符来自于您使用一台使用两个字符的物理打字机。一个用于将笔架放回到页面的左侧(CR-0xD),另一个导致将页面转到下一行(LF-0xA。)。我敢肯定有些人对此有更多了解然而。
mkgrunder

Answers:


288

您应该使用HEREDOC或NOWDOC。

$var = "some text";
$text = <<<EOT
  Place your text between the EOT. It's
  the delimiter that ends the text
  of your multiline string.
  $var
EOT;

Heredoc和Nowdoc之间的区别在于,将执行嵌入Heredoc中的PHP代码,而Nowdoc中的PHP代码将按原样打印出来。

$var = "foo";
$text = <<<'EOT'
  My $var
EOT;

在这种情况下,$ text将具有value My $var

注意:结束之前EOT;不应有空格或制表符。否则你会得到一个错误


为什么?因为第一个EOT和第二个EOT之间的所有内容都按原样视为字符串。这意味着您不需要在多行字符串中都加反斜杠n。@Fabian:HEREDOC和NOWDOC有什么区别,或者它们是同一回事?
肯尼·德罗布纳克

4
@powtac:否,因为它必须换行才能结束heredoc。具体来说,它EOT;之前必须没有空格。
Powerlord

我为Nowdoc添加了解释。
Halfdan

6
@halfdan,我想念什么吗?当我们只需键入“ Enter”键并将多行字符串与普通字符串一样用引号引起来时,为什么还要打扰heredocs和nowdocs ?
Pacerier 2015年

3
只需将其添加到您的答案中:在最后一个之前EOT;应该没有空格或制表符。否则会出现错误。
2013年

44

我使用与pix0r类似的系统,并且我认为这使代码更具可读性。有时,我实际上会尽量将换行符用双引号引起来,并在字符串的其余部分使用单引号。这样,如果您使用串联而不是将它们插入双引号字符串中,则它们会在其余文本中脱颖而出,并且变量也会更好地脱颖而出。因此,我可能会对您的原始示例执行以下操作:

$text = 'Hello ' . $vars->name . ','
      . "\r\n\r\n"
      . 'The second line starts two lines below.'
      . "\r\n\r\n"
      . 'I also don\'t want any spaces before the new line,'
      . ' so it\'s butted up against the left side of the screen.';

return $text;

关于换行符,对于电子邮件,您应始终使用\ r \ n。PHP_EOL用于要在与php运行相同的操作系统中使用的文件。


您是否在IDE中设置了该缩进(以设置与每个部分对齐的多行字符串)?
Krzysztof Trzos

25

我使用长文本模板:

email-template.txt包含

hello {name}!
how are you? 

在PHP中,我这样做:

$email = file_get_contents('email-template.txt');
$email = str_replace('{name},', 'Simon', $email);

有趣的...您将模板存储在Web应用程序的目录结构中的何处?
安德鲁2009年

我的代码只是一个演示。对于大型Web应用程序,您可以使用/ templates / emails /,/ templates / userfeedback /之类的结构。但是,如果您还有更多内容,我建议您使用SMARTY之类的完整模板系统。
powtac

Dwoo dwoo.org是一个不错的SMARTY兼容PHP模板系统,有人认为它是一个很好的继承者(始于PHP5,因此没有PHP4包bag)。
micahwittman,2009年

19

添加\n和/或\r像在第二个示例中那样,在字符串的中间在字符串中间,并且有很长的代码行,感觉并不正确:当您阅读代码时,看不到结果,因此必须滚动。

在这种情况下,我总是使用Heredoc (或者Nowdoc,如果使用PHP> = 5.3):易于编写,易于阅读,不需要超长行,...

例如 :

$var = 'World';
$str = <<<MARKER
this is a very
long string that
doesn't require
horizontal scrolling, 
and interpolates variables :
Hello, $var!
MARKER;

只是一件事:结束标记(及其后的' ;')必须是唯一的一件事:前后没有空格/制表符!


12

当然,您可以使用HEREDOC,但就代码可读性而言,它实际上并没有比第一个示例(将字符串跨多行包装)更好。

如果您确实希望多行字符串看起来不错并且代码运行顺畅,则建议将字符串串联在一起,如下所示:

$text = "Hello, {$vars->name},\r\n\r\n"
    . "The second line starts two lines below.\r\n"
    . ".. Third line... etc";

这可能比HEREDOC或多行字符串稍微慢一些,但它与代码的缩进配合得很好,并且更易于阅读。


9

对于Javascript,我更喜欢这种方法,但是似乎值得在这里包含它,因为它尚未被提及。

$var = "pizza";

$text = implode(" ", [
  "I love me some",
  "really large",
  $var,
  "pies.",
]);

// "I love me some really large pizza pies."

对于较小的事物,我发现使用数组结构通常比连接字符串更容易。

相关:爆裂vs连击性能


1

相信的人

"abc\n" . "def\n"

是多行字符串是错误的。那是带有串联运算符的两个字符串,而不是多行字符串。例如,此类串联字符串不能用作预定义数组的键。不幸的是,PHP不提供以下形式的真正的多行字符串:

"abc\n"
"def\n"

HEREDOCNOWDOC语法,这是更适合的模板,因为嵌套代码缩进被此类语法打破。


1

您还可以使用:

<?php
ob_start();
echo "some text";
echo "\n";

// you can also use: 
?> 
some text can be also written here, or maybe HTML:
<div>whatever<\div>
<?php
echo "you can basically write whatever you want";
// and then: 
$long_text = ob_get_clean();


0

但是换行和退货有什么关系呢?有什么不同?\ n \ n是否等于\ r \ r或\ n \ r?在行与行之间创建行距时应该使用哪个?

这里似乎没有人真的回答这个问题,所以我在这里。

\r 代表“回车”

\n 代表“换行”

他们的真正原因可以追溯到打字机。当您键入“笔架”时,它会慢慢地逐个字符地滑动到打字机的右侧。当您到达该行的末尾时,您将返回马车,然后转到新的行。要转到新行,您将翻转一个将行馈送到类型编写器的控制杆。因此,这些动作合起来称为回车换行。所以从字面上看:

换行\n表示移动到下一行。

回车, \r表示将光标移动到行首。

最终Hello\n\nWorld应在屏幕上显示以下输出:

Hello

     World

哪里Hello\r\rWorld应该导致以下输出

只有结合两个字符时\r\n,您才能对已知行有共同的理解。IE Hello\r\nWorld应该导致:

Hello
World

当然\n\r会产生与相同的视觉输出\r\n

原来电脑了\r\n毫不夸张。但是,这些天来回程运输的支持很少。通常,在每个系统上,您都可以独立使用\n。它从不依赖于操作系统,但确实取决于您正在查看输出的内容。

不过,我始终会建议\r\n您尽可能使用!

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.