Best Practices: working with long, multiline strings in PHP?
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?
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
andFOO;
- EOT : End of transmission, EOD: End of data. [Q]
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.
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);
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 !
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.
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
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();
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"
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.
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!
精彩评论