Strings7 min readExamples run on PHP 8.5.10

nl2br()

Learn how nl2br() inserts HTML line break tags before newlines in PHP 8.4, with examples, edge cases and the common escaping mistake.

Signature

nl2br(string $string, bool $use_xhtml = true): string

Purpose

Browsers collapse plain newline characters in HTML into ordinary whitespace, so a multi-line string from a textarea or a text file shows up as one run-on paragraph. nl2br() fixes this for display by putting an HTML line break tag in front of every newline in the string. The newline itself stays in place, so the source of the generated page remains readable.

Signature

Parameters and defaults

  • $string: the input text. Newlines can be \r\n, \n\r, \n or \r.
  • $use_xhtml: defaults to true, which inserts <br />. Pass false to insert the HTML-style <br> instead.

Return value and failure cases

The function always returns a string: the original text with a break tag inserted before each line ending. It has no error return value such as false. If you pass a value that cannot be used as a string, such as an array, PHP throws a TypeError. Under the default non-strict typing mode, scalar values like integers are converted to strings first.

Example 1: the basic call

The tag is added immediately before the newline, and the newline plus the following space are kept.

Example
<?php
echo nl2br("foo isn't\n bar");
Output
foo isn't<br />
 bar

The output is foo isn't<br />, a newline, then bar.

Example 2: mixed line endings and the HTML form

The combinations \r\n and \n\r count as a single line ending, so each pair gets one tag. A lone \n or lone \r also gets one. Here json_encode() makes the invisible control characters visible, and false selects <br>.

Example
<?php
$text = "A\r\nB\n\rC\nD\r";
echo json_encode(nl2br($text, false), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
Output
"A<br>\r\nB<br>\n\rC<br>\nD<br>\r"

Every one of the four line endings received exactly one <br>, and the original characters are untouched after it.

Example 3: escape first, then convert

User-supplied text must be escaped before it is placed in HTML. Because nl2br() adds real markup, call it after htmlspecialchars(), not before.

Example
<?php
$input = "Tom & Jerry <b>\nSecond line";
echo nl2br(htmlspecialchars($input));
Output
Tom &amp; Jerry &lt;b&gt;<br />
Second line

The ampersand and angle brackets are escaped, while the break tag added by nl2br() stays real markup.

Edge cases

  • A string without any newline is returned unchanged.
  • An empty string gives an empty string.
  • Consecutive newlines such as \n\n produce two tags, which is how blank lines stay visible.
  • The newline characters are not removed. If you need a single line of output, strip them separately.
  • A trailing newline at the end of the text also receives a tag, which can add an extra empty line at the end of a block.
  • The function does not wrap text in paragraph elements and does not look at existing HTML in the input. If the string already contains <br> tags, they are left alone and a new one is still added before each newline.

Common mistakes

  1. Calling it before escaping. If you run htmlspecialchars() after nl2br(), the break tags are escaped into visible text such as &lt;br /&gt;. Escape first, convert second.
  2. Assuming it is a sanitizer. nl2br() only inserts line breaks. It does nothing to stop script injection or broken markup.
  3. Expecting newlines to disappear. The original newline stays after the tag. In a browser this is harmless, but it matters when comparing strings or writing plain-text output.
  4. Using it for plain-text email or console output. Break tags are only meaningful in HTML. In a text context they show up as literal characters.
  5. Applying it to stored data. Keep the original text with its real newlines in storage and convert only when rendering, so the same data can be reused for other formats.
  6. Mixing it with white-space styling. If your CSS already preserves line breaks, adding nl2br() can double the visible spacing.
  • htmlspecialchars() converts special characters to HTML entities and should normally run before nl2br() on untrusted text.
  • htmlentities() converts all applicable characters to entities.
  • wordwrap() wraps text to a number of characters, which is a different layout concern.
  • str_replace() can perform custom newline replacement when you need a different tag or separator.

Recap

nl2br() inserts <br /> (or <br> with false) before every line ending in a string and returns the result. It treats \r\n and \n\r as one line ending, leaves the newline characters in place, and does no escaping. Escape untrusted input with htmlspecialchars() first, then call nl2br() only when producing HTML output.

Tested examples

Basic nl2br() call with the default XHTML tag
<?php
echo nl2br("foo isn't\n bar");
Output
foo isn't<br />
 bar
Mixed line endings with use_xhtml set to false
<?php
$text = "A\r\nB\n\rC\nD\r";
echo json_encode(nl2br($text, false), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
Output
"A<br>\r\nB<br>\n\rC<br>\nD<br>\r"
Escape with htmlspecialchars() before nl2br()
<?php
$input = "Tom & Jerry <b>\nSecond line";
echo nl2br(htmlspecialchars($input));
Output
Tom &amp; Jerry &lt;b&gt;<br />
Second line