nl2br

Inserts an HTML line break before every newline in a string.

Signature
nl2br(string $string, bool $use_xhtml = true): string
  • Added in PHP 4.0

Parameters

ParameterTypeDescription
$stringstringThe input string.
$use_xhtmloptionalbool= trueWhether to emit XHTML-compatible <br /> instead of HTML <br>.

Return value

stringThe string with <br /> or <br> inserted before every newline sequence.

nl2br takes text that carries real newlines — a textarea submission, a database TEXT column, a plain-text email body — and makes it render with the same line structure inside HTML, where a bare newline collapses to a space. It recognises all four newline forms: \r\n, \n\r, \n and \r, and treats each pair as a single break.

It inserts, it does not replace

The newline stays in the output. nl2br("one\ntwo") returns one<br />\ntwo, not one<br />two. That is deliberate — it keeps the generated HTML source readable — but it means the output is longer than you might expect and that a strlen comparison will surprise you. If you genuinely want the newline gone, use str_replace.

Escape first, then convert

This is the security-relevant part. nl2br does no escaping whatsoever; anything else in the string, including <script>, passes straight through. Always run htmlspecialchars first and nl2br second. Doing it the other way round escapes the <br /> tags you just inserted and prints them as literal text.

Pass false as the second argument for HTML5 output (<br>); the default remains the XHTML form for backward compatibility. In many templates a CSS white-space: pre-line rule is a cleaner answer than converting at all.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Render a user comment or product review submitted through a textarea with its paragraph breaks intact.
  • Display a plain-text address block stored in one database column on an order confirmation page.
  • Turn a plain-text email body into HTML for a preview pane.

Frequently asked questions

Why does nl2br leave the newline in the output?

By design — it inserts the <br> tag before the newline rather than replacing it, which keeps the generated HTML source readable. Use str_replace("\n", '<br>', $s) if you need the newline removed.

How do I get <br> instead of <br /> from nl2br?

Pass false as the second argument: nl2br($text, false). The default is true for XHTML compatibility, but HTML5 pages normally want the short form.

Is nl2br safe against XSS?

No. It performs no escaping at all. Run htmlspecialchars() on the untrusted text first and pass its result to nl2br, never the other way round.

More examples

The newline is kept, not replaced

nl2br returns a 13-byte string `one<br />\ntwo` — the `\n` is still there after the tag. str_replace returns 10 bytes, `one<br>two`, with the newline actually gone. Use str_replace when the trailing newline matters (for example when you are counting bytes or generating minified output).

Example · php
<?php
$s = "one\ntwo";
var_dump(nl2br($s));
var_dump(str_replace("\n", '<br>', $s));

Escaping order matters

The first output contains a live `<script>` tag: nl2br passed it through untouched. The second escapes it to `&lt;script&gt;alert(1)&lt;/script&gt;` while still producing a working `<br />`. Escaping first and converting second is the only safe order.

Example · php
<?php
$unsafe = "Hello <script>alert(1)</script>\nSecond line";

echo nl2br($unsafe), PHP_EOL;
echo '---', PHP_EOL;
echo nl2br(htmlspecialchars($unsafe, ENT_QUOTES)), PHP_EOL;

Discussion

  • Be the first to comment on this lesson.