Best Practices: working with long, multiline strings in PHP? - 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 and FOO;
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!

Related

Backslashes breaking string in PHP

I have an issue. I'm trying to write a string with ASCII text like this: '/\'. But whenever I do that the backslash screws up the code by canceling out the quote defining it a string therefore screwing it up. Is there anyway to cancel out the backslash so it doesn't cancel out the quote? Thanks guys!
The \ is special character, that says: 'The next character has special meaning'.
So if you want to dispaly \ you should write... \\ to get one \ in output
It would be very helpful to show what you have tried, but this will produce the exact output you requested (as shown by SO)
echo '\'/\\' . "'\n" ;
'/\'
It should also give you an idea of how backslash escaping works in different types of strings.
A great solution when writing stuff like that is HEREDOC. Inside a heredoc block you don't need to worry about escaping anything, it will just be text.
For example:
echo <<<TEXT
/|\/|\/|\/|\/|\/|\/|\/|\/|\/|\
TEXT;
There is one catch. PHP will break if you don't align the echo at the start of the line, or if the TEXT; is not aligned at the start of the line.
Heredoc can also be assigned to a variable, like so:
$var = <<<SOME_MORE_TEXT
/|\/|\/|\/|\/|\/|\/|\/|\/|\/|\
SOME_MORE_TEXT;
Finally, HEREDOC preserves tabs and spaces. Which also might come in handy when doing ASCII art.
Refer to: http://php.net/manual/en/language.types.string.php for more information.
You only need to escape the final one when using single quotes.
$var = 'backslash\backslash\backslash\\';
// output is:
// backslash\backslash\backslash\

Can't see new lines on textarea - what could the problem be?

I have a php string with a lot of information to be displayed inside a textarea html element.
I don't have access to that textarea nor to the script (if any) that generates it.
$somestring = 'first line \nSecond line \nThird line.';
$somestring as NOT been "worked" with trim or filter_var. Nothing.
On the textfield, I get the \n printed on the textarea hence, not interpreted.
What can I try in order to have those new lines applied?
Thanks in advance.
Try wrapping $somestring with " (double quotes) instead of ' (single quotes)
\n, \r and other backslash escape characters only works in double quotes and heredoc. In single quotes and nowdoc (the single quote version of heredoc), they are read as literal \n and \r.
Example:
<?php
echo "Hello\nWorld"; // Two lines: 'Hello' and 'World'
echo 'Hello\nWorld'; // One line: literally 'Hello\nWorld'
echo <<<HEREDOC
Hello\nWorld
HEREDOC; // Same as "Hello\nWorld"
echo <<<'NOWDOC'
Hello\nWorld
NOWDOC; // Same as 'Hello\nWorld' - only works in PHP 5.3.0+
Read more about this behaviour in the PHP manual
EDIT:
The reason single and double quotes behave differently is because they are both needed in different situations.
For instance, if you would have a string with a lot of new lines, you would use double quotes:
echo "This\nstring\nhas\na\nlot\nof\nlines\n";
But if you would use a string with a lot of backslashes, such as a file name (on Windows) or a regular expression, you would use single quotes to simplify it and avoid having unexpected problems by forgetting to escape a backslash:
echo "C:\this\will\not\work"; // Prints a tab instead of \t and a newline instead of \n
echo 'C:\this\would\work'; // Prints the expected string
echo '/regular expression/'; // Best way to write a regular expression
$somestring = "first line \nSecond line \nThird line.";
http://php.net/types.string <-- extremely useful reading
this article is a cornerstone of PHP knowledge and it's just impossible to use PHP without it.
unlike most of manual pages which are are just for quick reference, this very page is one which every developer should learn by heart.

In PHP: If I start a new line while writing a string in my source is it necessary to concatenate the string?

I'm learning PHP and MySQL together from Head First PHP & MySQL and in the book, they often split their long strings (over 80~ characters) and concatenate them, like this:
$variable = "a very long string " .
"that requires a new line " .
"and apparently needs to be concatenated.";
I have no issue with this, but what strikes me odd is that whitespace in other languages usually don't need concatenation.
$variable = "you guys probably already know
that this simply works too.";
I tried this and it worked just fine. Aren't line breaks always interpreted with a space at the end? Even the PHP manual doesn't concatenate in the echo examples if they span over one line.
Should I follow my book's example or what? I can't tell which is more correct or "proper" since both work and the manual even takes a shorter approach. I also would like to know how important is it to keep code under 80 characters in width? I have always been fine with word warp since my monitor is pretty large and I hate my code getting cut short when I have the screen space.
There's 3 basic ways of building multiline strings in PHP.
a. building string via concatenation and embedded newlines:
$str = "this is the first line, with a line break\n";
$str .= "this is the second line, but won't have a break";
$str .= "this would've been the 3rd line, but since there's no line break in the previous line..."`
b. multi-line string assignment, with embedded newlines:
$str = "this is the first line, with a line break\n
this is the second line, because of the line break.
this line will actually is actually part of the second line, because of no newline";
c. HEREDOC syntax:
$str = <<<EOL
this is the first line
this is the second line, note the lack of a newline
this is the third line\n
this is actually the fifth line, because the newline previously isn't necessary.
EOL;
Heredocs are generally preferable for building multi-line strings. You don't have to escape quotes within the text, variables are interpolated within them as if it was a regular double-quoted string, and newlines within the text are honored.
In PHP long strings don't need concatenation but keep in mind that:
$variable = "you guys probably already know
that this simply works too.";
is the equivalent of
$variable = "you guys probably already know\nthat this simply works too.";
The newline is just the same in these 2 examples (if your system uses \n as a newline - Windows uses \r\n).
So to answer your question, no, you don't have to break large strings in many smaller ones. Doing so is just a matter of preference (which I don't really often see).
The 80 char "limit" is throwback to the old days where terminal screens had an 80 char width. If you ever need to edit something in a narrow width terminal, respecting 80 chars can be helpful. However, if longer than 80 char lines wrapping are causing you headaches in your editor, Don't follow that convention.
When you have a multi-line string as in your second example, the string will be exactly as you type it in your editor. If you have a whole bunch of spaces before your retrun char, those will be in your string var. The only exception to this is if your editor is doing line wrapping, then there is not actually a return char in the string, and it won't show up in the variable.
PHP syntax allows literal line feeds in the strings. Your second example equals this:
you guys probably already know[LF][SPACE][SPACE][SPACE][SPACE]that this simply works too.
where [LF] will be \r\n or \n depending on your editor settings. Those redundant spaces may be an issue or not (not everything is HTML), but it's not the same as concatenating.
No.
1) open quotes
2) write as much as you need, adding spaces, tabs, whatever else
3) close quotes.
If you're using the same quotes within, escape them with \
"Jane said \"It's hot today!\"";
or
'Jane said "It\'s hot today!"';

PHP long string without newline

I have a long string in php which does not contain new lines ('\n').
My coding convention does not allow lines longer than 100 characters.
Is there a way to split my long string into multiple lines without using the . operator which is less efficient - I don't need to concat 2 strings as they can be given as a
single string.
Thanks!
Y
This is the right code, that solved all issues:
$myStr = "
here is my string
and it is spread across multiple lines
";
$myStr = str_replace(array("\r","\n"), "", $myStr);
It is based on Lior Cohen's answer, but it also strips carriage returns "\r".
With the heredoc syntax (or nowdoc, depending on your needs, check the documentation link):
$multiline = <<<EOT
My name is "$name". I am printing some $foo->foo.
This should print a capital 'A': \x41
EOT;
$singleline = str_replace("\n","",$multiline);
But this sucks... sorry :-)
You could strip newline characters from the string:
$myStr = "
here is my string
and it is spread across multiple lines
";
$myStr = str_replace("\n", "", $myStr);
You should still use the concatenation operator (.) for such things. The performance penalty here is negligible if you're using opcode caching (APC) and this would really not be anything noticeable when taking DB access and additional logic (including loops) into the run time equation.
Update:
Give the page below a read. The conclusion above is not readily available in the text, but a careful examination should show it is valid.
http://blog.golemon.com/2006/06/how-long-is-piece-of-string.html

PHP, why sometimes "\n or \r" works but sometimes doesnt?

Well, I am abit confuse using these \r,\n,\t etc things. Because I read online (php.net), it seems like works, but i try it, here is my simple code:
<?php
$str = "My name is jingle \n\r";
$str2 = "I am a boy";
echo $str . $str2;
?>
But the outcome is "My name is jingle I am a boy"
Either I put the \r\n in the var or in the same line as echo, the outcome is the same. Anyone knows why?
Because you are outputting to a browser, you need to use a <br /> instead, otherwise wrap your output in <pre> tags.
Try:
<?php
$str = "My name is jingle <br />";
$str2 = "I am a boy";
echo $str . $str2;
?>
Or:
<?php
$str = "My name is jingle \n\r";
$str2 = "I am a boy";
echo '<pre>' .$str . $str2 . '</pre>';
?>
Browsers will not <pre>serve non-HTML formatting unless made explicit using <pre> - they are interested only in HTML.
Well in your example you've got \n\r rather than \r\n - that's rarely a good idea.
Where are you seeing this outcome? In a web browser? In the source of a page, still in a web browser? What operating system are you using? All of these make a difference.
Different operating systems use different line terminators, and HTML/XML doesn't care much about line breaking, in that the line breaks in the source just mean "whitespace" (so you'll get a space between words, but not necessarily a line break).
You could also use nl2br():
echo nl2br($str . $str2);
What this function does is replace newline characters in your string to <br>.
Also, you don't need \r, just \n.
In HTML, spaces, tabs, linefeeds and carriage returns are all equivalent white space characters.
In text, historically the following combinations have been used for newlines
\r on Apple Macs
\r\n on Windows
\n on Unix
Either use \n (*NIX) or \r\n (DOS / Windows), \n\r is very uncommon. Once you fix that, it should work just fine.
Of course, if you're outputting HTML, a line break does nothing unless it's inside <pre></pre> tags. Use <br /> to separate lines in HTML. The nl2br() function can help you to convert line breaks to HTML if needed.
Also, if you use single-quoted strings (your example has double quoted strings), \r and \n will not work. The only escape characters available in single quoted strings are \' and \.
Are you displaying the results in an HTML page? if so, HTML strips whitespace like newlines. You'd have to something like use '<br />' instead of '/r/n' in HTML.

Categories