「改行を <br> に変換」とは何をしているのか
テキストエリアなどから受け取った文字列には、ユーザーが入力した「改行」が含まれています。
でも、そのまま HTML に出力すると、ブラウザは改行文字(\n など)を「ただの空白」として扱い、行は変わりません。
$text = "1行目\n2行目\n3行目";
echo $text; // ブラウザ上では 1行に見える
PHPブラウザに「ここで行を変えてほしい」と伝えるには、HTML の改行タグ <br> が必要です。
つまりやりたいことは、
文字列の中の「改行コード」を、HTML の
<br>に置き換える
ということです。
PHP の定番:nl2br 関数の基本
nl2br の動き
PHP には、改行を <br> に変換するための専用関数 nl2br があります。
$text = "1行目\n2行目\n3行目";
echo nl2br($text);
PHPブラウザで見ると、ちゃんとこう表示されます。
1行目
2行目
3行目
nl2br は、文字列の中の改行コード(\n)を、HTML の <br> に変換してくれる関数です。
CRLF(\r\n)や CR(\r)もどうなる?
実務では、改行コードが混在していることがあります。
- Linux / macOS:LF(
\n) - Windows:CRLF(
\r\n) - 古い Mac:CR(
\r)
nl2br は、基本的に \n を対象にしますが、\r\n の場合もちゃんと処理されます(\r\n の中の \n が変換されるイメージ)。
ただし、改行コードがぐちゃぐちゃなデータを扱うときは、事前に「改行コードを LF に統一」しておくとより安定します。
超重要ポイント:XSS 対策としての「順番」
ここが一番大事なところです。
改行を
<br>に変換する前に、必ず HTML エスケープをする
という順番を守ってください。
なぜ順番が大事なのか
ユーザー入力をそのまま nl2br に通して出力すると、
ユーザーが書いた HTML や JavaScript が、そのままブラウザで「動く」可能性があります。
$comment = $_POST['comment'] ?? '';
echo nl2br($comment); // 危険なパターン
PHPもしユーザーがこんな入力をしたらどうなるでしょう。
こんにちは<br><script>alert('XSS');</script>
nl2br は改行だけを <br> に変換するので、<script> はそのまま残ります。
その結果、ブラウザで JavaScript が実行されてしまいます。
正しい順番:htmlspecialchars → nl2br
安全に表示したいときの基本パターンはこれです。
$comment = $_POST['comment'] ?? '';
// 1. HTML エスケープ(タグを「ただの文字」にする)
$safe = htmlspecialchars($comment, ENT_QUOTES, 'UTF-8');
// 2. 改行を <br> に変換
$safe = nl2br($safe);
// 3. 画面に出力
echo $safe;
PHPこうすると、ユーザーが <script> と書いても、画面上には
<script>alert('XSS');</script>
と表示され、タグとしては動きません。
そのうえで、改行だけが <br> に変換されるので、「安全に」「見た目もきれいに」表示できます。
この「エスケープ → 改行変換」の順番は、実務で本当に重要なパターンなので、手癖にしてしまってください。
実務での具体的なシチュエーション例
例題1:お問い合わせフォームの内容をそのまま表示したい
お問い合わせフォームの「内容」欄は、複数行のテキストが入ることが多いです。
$message = $_POST['message'] ?? '';
PHPこれを管理画面で見やすく表示したいときのコードは、こうなります。
$message = $_POST['message'] ?? '';
$safe = htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
$safe = nl2br($safe);
echo $safe;
PHPこれで、
- ユーザーが入力した改行は
<br>になって行が変わる - HTML や JavaScript は「ただの文字」として表示される
という、実務で理想的な状態になります。
例題2:プロフィールの自己紹介文を表示する
ユーザーが自分のプロフィールに「自己紹介文」を書ける機能を考えます。
$bio = $user['bio'] ?? '';
PHP自己紹介文はテキストエリアで入力されることが多く、改行をそのまま見せたいですよね。
$safeBio = htmlspecialchars($bio, ENT_QUOTES, 'UTF-8');
$safeBio = nl2br($safeBio);
echo $safeBio;
PHPこれで、ユーザーが入力した改行がそのまま画面に反映され、
かつ HTML としては安全な表示になります。
nl2br の細かい挙動とオプション
<br> か <br /> か
nl2br には、第2引数に「false を渡すと <br>、true を渡すと <br />」という挙動があります(PHP 5.3 以降)。
$text = "1行目\n2行目";
// デフォルト(第2引数省略 or true): <br />
echo nl2br($text); // 1行目<br />\n2行目
// HTML5 で <br> にしたい場合
echo nl2br($text, false); // 1行目<br>\n2行目
PHP最近の HTML5 では <br> で十分なので、気になる場合は false を渡しておくとよいです。
ただし、どちらでもブラウザは正しく解釈してくれます。
すでに <br> が入っている場合
ユーザーが自分で <br> と書いている場合、それはそのまま文字として扱うか、
あるいはそもそも HTML として許可するか、設計次第です。
「ユーザーの <br> をタグとして動かしたくない」なら、
やはり先に htmlspecialchars でエスケープしておくのが安全です。
改行コードがバラバラな場合の一工夫
先に「改行コードを LF に統一」しておく
Windows からの入力や外部ファイルなどで、改行コードが混ざっている可能性がある場合は、nl2br の前に「改行コードを LF に統一」しておくと、より安定します。
簡単なユーティリティ関数はこんな感じです。
function normalizeNewlineToLF(string $text): string
{
$text = str_replace("\r\n", "\n", $text); // CRLF -> LF
$text = str_replace("\r", "\n", $text); // CR -> LF
return $text;
}
PHPこれを組み合わせると、こうなります。
$comment = $_POST['comment'] ?? '';
$comment = normalizeNewlineToLF($comment);
$safe = htmlspecialchars($comment, ENT_QUOTES, 'UTF-8');
$safe = nl2br($safe);
echo $safe;
PHPこうしておけば、どんな環境から来た改行でも、
最終的にはきれいに <br> に変換されます。
まとめ:今日から使える「改行を <br> に変換」テンプレ
実務でほぼそのまま使える、鉄板パターンをまとめておきます。
もっともよく使う安全な表示パターン
function escapeAndNl2br(string $text): string
{
// 改行コードを LF にそろえておくとより安定
$text = str_replace("\r\n", "\n", $text);
$text = str_replace("\r", "\n", $text);
// HTML エスケープ
$text = htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
// 改行を <br> に変換(HTML5 なら false 推奨)
$text = nl2br($text, false);
return $text;
}
// 使い方
$comment = $_POST['comment'] ?? '';
echo escapeAndNl2br($comment);
PHPこの関数を「ビューに出す直前の共通処理」として使うだけで、
- 改行はちゃんと
<br>になる - HTML や JavaScript はそのまま動かない
- 改行コードの違いにもそこそこ強い
という、実務レベルでかなり安定した表示が手に入ります。
