190

Note: I'm sorry if this is an extremely simple question but I'm somewhat obsessive compulsive over the formatting of my code.

I have a class that has a function that returns a string that will make up the body text of an email. I want this text formatted so it looks right in the email, but also so it doesn't make my code look funky. Here's what I mean:

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;
    }
}

but it could also be written as:

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;
}

but what's the deal with new lines and carriage returns? What's the difference? Is \n\n the equivalent of \r\r or \n\r? Which should I use when I'm creating a line gap between lines?

Then there's the option of output buffering and heredoc syntax.

How do you deal with using long multiline strings in your objects?

DC Slagel
  • 528
  • 1
  • 7
  • 13
Andrew
  • 227,796
  • 193
  • 515
  • 708
  • 4
    I'd always thought that \n was newline in Unix \r is newline on MacOS before OS/X, and \r\n is newline on Windows. Also, considering this is going to be a string that shows up in an email message, you'll want to make sure that whichever way you are doing it shows up correctly on most command mail clients. Hint: Outlook removes extra newline characters in some cases, so you won't always get what you expect. – Kenny Drobnack Dec 04 '09 at 19:08
  • 1
    Not sure if it's all that important, but originally the two 'newline' characters came from when you had a physical typewriter that used two characters. One for putting the carriage back to the left hand side of the page (CR - 0xD), and one that caused the page to go to the next line (LF - 0xA.) I'm sure there are people who know more regarding this however. – mkgrunder Dec 04 '09 at 20:48

10 Answers10

317

You should use heredoc or 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;

The difference between heredoc and nowdoc is that PHP code embedded in a heredoc gets executed, while PHP code in nowdoc will be printed out as is.

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

In this case $text will have the value "My $var", not "My foo".

Notes:

  • Before the closing EOT; there should be no spaces or tabs. otherwise you will get an error.
  • The string/tag (EOT) that enclose the text is arbitrary, that is, one can use other strings, e.g. <<<FOO and FOO;
  • EOT : End of transmission, EOD: End of data. [Q]
akinuri
  • 10,690
  • 10
  • 65
  • 102
halfdan
  • 33,545
  • 8
  • 78
  • 87
  • Why? Because everything between the first EOT and the second is considered to be a string as-is. Which means you don't need to put backslash n all over your multi-line strings. @Fabian: What is the difference between a HEREDOC and NOWDOC, or are they the same thing? – Kenny Drobnack Dec 04 '09 at 19:11
  • 4
    @powtac: No, because it has to be on a new line to end a heredoc. Specifically, it has to be `EOT;` with no spaces before it. – Powerlord Dec 04 '09 at 19:13
  • I have added an explanation for Nowdoc. – halfdan Dec 04 '09 at 19:37
  • Fabian, Thanks for the explanation of NOWDOC. It's been a while since I've done PHP. I mostly do Perl now and have used HEREDOC quite a few times. I've never even heard of NOWDOC before. Have to see if Perl supports it. – Kenny Drobnack Dec 04 '09 at 21:00
  • 7
    @halfdan, Am I missing something? Why bother with heredocs and nowdocs when we can [simply type the "Enter" key](http://stackoverflow.com/questions/9744192/php-multi-line-strings/9744216#9744216) and surround the multi-line string with quotes just like a normal string? – Pacerier Apr 05 '15 at 14:09
  • Unfortunately, HEREDOC adds unwanted line-endings to your string. – Bobby Jack Oct 20 '15 at 17:19
  • 4
    Just please add this to your answer: before the last `EOT;` there should be no spaces or tabs. otherwise you will get an error. – Shnd Dec 07 '16 at 20:13
  • @Pacerier great point. id love to know the reasoning for using `EOT` over that too!! – oldboy Aug 02 '19 at 21:04
  • @Pacerier ive actually decided to use `EOT` for formatting purposes – oldboy Aug 03 '19 at 02:32
48

I use similar system as pix0r and I think that makes the code quite readable. Sometimes I would actually go as far as separating the line breaks in double quotes and use single quotes for the rest of the string. That way they stand out from the rest of the text and variables also stand out better if you use concatenation rather than inject them inside double quoted string. So I might do something like this with your original example:

$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;

Regarding the line breaks, with email you should always use \r\n. PHP_EOL is for files that are meant to be used in the same operating system that php is running on.

Cvuorinen
  • 1,319
  • 1
  • 11
  • 14
  • Did you set that indentation in Your IDE (to set multilined string aligned to each part)? – Jazi Jun 15 '16 at 11:44
27

I use templates for long text:

email-template.txt contains

hello {name}!
how are you? 

In PHP I do this:

$email = file_get_contents('email-template.txt');
$email = str_replace('{name},', 'Simon', $email);
powtac
  • 40,542
  • 28
  • 115
  • 170
  • interesting...where do you store your templates in the directory structure of a web application? – Andrew Dec 04 '09 at 19:26
  • My code is just a demo. For a huge web app you might use a structure like /templates/emails/ , /templates/userfeedback/. But if you have more stuff I would recommend a full template system like SMARTY. – powtac Dec 04 '09 at 19:42
  • Dwoo http://dwoo.org/ is a decent SMARTY-compatible PHP templating system which some consider a good successor (started on PHP5, so no PHP4 baggage). – micahwittman Dec 04 '09 at 20:48
19

Adding \n and/or \r in the middle of the string, and having a very long line of code, like in second example, doesn't feel right : when you read the code, you don't see the result, and you have to scroll.

In this kind of situations, I always use Heredoc (Or Nowdoc, if using PHP >= 5.3) : easy to write, easy to read, no need for super-long lines, ...

For instance :

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

Just one thing : the end marker (and the ';' after it) must be the only thing on its line : no space/tab before or after !

micahwittman
  • 12,356
  • 2
  • 32
  • 37
Pascal MARTIN
  • 395,085
  • 80
  • 655
  • 663
14

Sure, you could use HEREDOC, but as far as code readability goes it's not really any better than the first example, wrapping the string across multiple lines.

If you really want your multi-line string to look good and flow well with your code, I'd recommend concatenating strings together as such:

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

This might be slightly slower than HEREDOC or a multi-line string, but it will flow well with your code's indentation and make it easier to read.

pix0r
  • 31,139
  • 18
  • 86
  • 102
13

I like this method a little more for Javascript but it seems worth including here because it has not been mentioned yet.

$var = "pizza";

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

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

For smaller things, I find it is often easier to work with array structures compared to concatenated strings.

Related: implode vs concat performance

Community
  • 1
  • 1
johnny
  • 327
  • 3
  • 10
1

you can also use:

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

Alon Gouldman
  • 3,025
  • 26
  • 29
0

In regards to your question about newlines and carriage returns:

I would recommend using the predefined global constant PHP_EOL as it will solve any cross-platform compatibility issues.

This question has been raised on SO beforehand and you can find out more information by reading "When do I use the PHP constant PHP_EOL"

Community
  • 1
  • 1
Corey Ballou
  • 42,389
  • 8
  • 62
  • 75
  • 1
    The comment to this answer suggests that I should use \r\n for new lines in emails: http://stackoverflow.com/questions/128560/when-do-i-use-the-php-constant-phpeol/699754#699754 – Andrew Dec 04 '09 at 19:24
0

The one who believes that

"abc\n" . "def\n"

is multiline string is wrong. That's two strings with concatenation operator, not a multiline string. Such concatenated strings cannot be used as keys of pre-defined arrays, for example. Unfortunately php does not offer real multiline strings in form of

"abc\n"
"def\n"

only HEREDOC and NOWDOC syntax, which is more suitable for templates, because nested code indent is broken by such syntax.

NappingRabbit
  • 1,888
  • 1
  • 13
  • 18
Dmitriy Sintsov
  • 3,821
  • 32
  • 20
0

but what's the deal with new lines and carriage returns? What's the difference? Is \n\n the equivalent of \r\r or \n\r? Which should I use when I'm creating a line gap between lines?

No one here seemed to actualy answer this question, so here I am.

\r represents 'carriage-return'

\n represents 'line-feed'

The actual reason for them goes back to typewriters. As you typed the 'carriage' would slowly slide, character by character, to the right of the typewriter. When you got to the end of the line you would return the carriage and then go to a new line. To go to the new line, you would flip a lever which fed the lines to the type writer. Thus these actions, combined, were called carriage return line feed. So quite literally:

A line feed,\n, means moving to the next line.

A carriage return, \r, means moving the cursor to the beginning of the line.

Ultimately Hello\n\nWorld should result in the following output on the screen:

Hello

     World

Where as Hello\r\rWorld should result in the following output.

It's only when combining the 2 characters \r\n that you have the common understanding of knew line. I.E. Hello\r\nWorld should result in:

Hello
World

And of course \n\r would result in the same visual output as \r\n.

Originally computers took \r and \n quite literally. However these days the support for carriage return is sparse. Usually on every system you can get away with using \n on its own. It never depends on the OS, but it does depend on what you're viewing the output in.

Still I'd always advise using \r\n wherever you can!

Sancarn
  • 2,575
  • 20
  • 45