nl2br
Inserts an HTML line break before every newline in a string.
nl2br(string $string, bool $use_xhtml = true): string- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$string | string | The input string. |
$use_xhtmloptional | bool= true | Whether 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
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).
<?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 `<script>alert(1)</script>` while still producing a working `<br />`. Escaping first and converting second is the only safe order.
<?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