【问题标题】:Best Practices: working with long, multiline strings in PHP?最佳实践:在 PHP 中使用长的多行字符串?
【发布时间】:2010-12-23 08:47:07
【问题描述】:

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

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

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语法的选项。

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

【问题讨论】:

  • 我一直认为 \n 是 Unix 中的换行符 \r 是 OS/X 之前的 MacOS 上的换行符,而 \r\n 是 Windows 上的换行符。此外,考虑到这将是一个显示在电子邮件消息中的字符串,您需要确保无论您采用哪种方式,它都能在大多数命令邮件客户端上正确显示。提示:Outlook 在某些情况下会删除额外的换行符,因此您不会总是得到预期的结果。
  • 不确定这是否那么重要,但最初这两个“换行”字符来自使用两个字符的物理打字机。一个用于将马车放回页面的左侧(CR - 0xD),另一个导致页面转到下一行(LF - 0xA。)我相信有人对此了解更多但是。

标签: php string


【解决方案1】:

您应该使用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 的值将是 "My $var",而不是 "My foo"。

注意事项:

  • EOT; 结束前不应有空格或制表符。否则会报错。
  • 包围文本的字符串/标签 (EOT) 是任意的,即可以使用其他字符串,例如&lt;&lt;&lt;FOO 和 FOO;
  • EOT:传输结束,EOD:数据结束。 [Q]

【讨论】:

  • 为什么?因为第一个 EOT 和第二个 EOT 之间的所有内容都被认为是一个字符串。这意味着您不需要在多行字符串中放置反斜杠 n。 @Fabian:HEREDOC 和NOWDOC 有什么区别,或者它们是同一个东西?
  • @powtac:不,因为它必须在新行上才能结束heredoc。具体来说,它必须是EOT;,前面没有空格。
  • 我已经为Nowdoc添加了解释。
  • @halfdan,我错过了什么吗?当我们可以 simply type the "Enter" key 并像普通字符串一样用引号将多行字符串括起来时,为什么还要打扰 heredocs 和 nowdocs?
  • 请将此添加到您的答案中:在最后一个 EOT; 之前不应有空格或制表符。否则会报错。
【解决方案2】:

我使用与 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 中设置了缩进(设置多行字符串与每个部分对齐)?
【解决方案3】:

我对长文本使用模板:

email-template.txt 包含

hello {name}!
how are you? 

在 PHP 中我这样做:

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

【讨论】:

  • 有趣...您将模板存储在 Web 应用程序的目录结构中的什么位置?
  • 我的代码只是一个演示。对于大型网络应用程序,您可能会使用 /templates/emails/ 、 /templates/userfeedback/ 之类的结构。但是如果你有更多的东西,我会推荐一个完整的模板系统,比如 SMARTY。
  • Dwoo dwoo.org 是一个不错的兼容 SMARTY 的 PHP 模板系统,有些人认为它是一个很好的继任者(从 PHP5 开始,所以没有 PHP4 包袱)。
【解决方案4】:

在字符串中间添加\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;

只有一件事:结束标记(以及它之后的“;”)必须是其行上唯一的东西:之前或之后没有空格/制表符!

【讨论】:

    【解决方案5】:

    当然,您可以使用 HEREDOC,但就代码可读性而言,它并不比第一个示例更好,将字符串包装成多行。

    如果您真的希望您的多行字符串看起来不错并且与您的代码流畅,我建议您将字符串连接在一起:

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

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

    【讨论】:

      【解决方案6】:

      我更喜欢这种用于 Javascript 的方法,但它似乎值得在这里包含,因为它还没有被提及。

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

      对于较小的事情,我发现与串联字符串相比,使用数组结构通常更容易。

      相关:implode vs concat performance

      【讨论】:

        【解决方案7】:

        相信的人

        "abc\n" . "def\n"
        

        是多行字符串是错误的。那是两个带有连接运算符的字符串,而不是多行字符串。例如,这种连接的字符串不能用作预定义数组的键。不幸的是,php 不提供真正的多行字符串

        "abc\n"
        "def\n"
        

        只有HEREDOC和NOWDOC语法,更适合模板,因为嵌套代码缩进被这种语法破坏了。

        【讨论】:

          【解决方案8】:

          你也可以使用:

          <?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();
          
          

          【讨论】:

            【解决方案9】:

            关于换行和回车的问题:

            我建议使用预定义的全局常量 PHP_EOL,因为它可以解决任何跨平台兼容性问题。

            这个问题已经提前在 SO 上提出,您可以通过阅读“When do I use the PHP constant PHP_EOL”了解更多信息

            【讨论】:

            【解决方案10】:

            但是换行和回车是怎么回事?有什么不同? \n\n 是否等同于 \r\r 或 \n\r?当我在线条之间创建线条间隙时应该使用哪个?

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

            \r 代表'回车'

            \n 代表'换行'

            它们的真正原因可以追溯到打字机。当您键入时,“马车”会逐个字符缓慢地滑到打字机的右侧。当您到达行尾时,您会返回马车,然后换行。要转到新行,您需要拨动一个杠杆,将行输入 给打字员。因此,这些操作组合起来称为回车换行。从字面上看:

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

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

            最终Hello\n\nWorld 应该会在屏幕上产生以下输出:

            Hello
            
                 World
            

            Hello\r\rWorld 的结果应该是 the following output。

            只有将\r\n这2个字符组合起来,才对know line有共同的理解。 IE。 Hello\r\nWorld 应该会导致:

            Hello
            World
            

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

            最初计算机完全按照字面意思使用\r 和\n。然而,这些天对回车的支持很少。通常在每个系统上,您都可以单独使用\n。它从不依赖于操作系统,但它确实取决于您查看输出的内容。

            我仍然建议尽可能使用\r\n!

            【讨论】:

              猜你喜欢
              • 2014-01-23
              • 2017-12-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-06-08
              • 1970-01-01
              • 2012-04-10
              相关资源
              最近更新 更多