はじめに
Web開発において、文字列中の「改行」や「エスケープ文字」の扱いは、環境や言語によって挙動が異なるため混乱しがちです。
特に \n(改行)に関しては、
- 文字としての「\n」なのか
- 実際の改行文字(LF)なのか
を意識しないと、意図せぬ表示や保存の問題に直面します。
本記事では、JSON → PHP(Laravel) → MySQL という一般的なデータフローを通して、改行やエスケープの扱いを整理し、よくあるユースケース別にベストプラクティスをまとめます。
各技術における改行とエスケープの仕様
JSON の場合
| 表現 | 意味 |
|---|---|
\n |
改行(LF)を意味するエスケープ文字 |
\\n |
バックスラッシュ・n(文字としての \n) |
{"text":"1行目\n2行目"} // → 改行される
{"text":"1行目\\n2行目"} // → 「\n」という文字列になる
PHP の場合
文字列リテラルの違い
普段そこまで意識しませんが、PHPではダブルクォートで囲むか、シングルクォートで囲むかによってエスケープ文字列の扱いが変わります。
| リテラル | 解釈 | 備考 |
|---|---|---|
"1行目\n2行目" |
改行が入る | エスケープシーケンスが展開される |
'1行目\n2行目' |
バックスラッシュ・n | エスケープされず文字列のまま |
json_decode() の挙動
- JSONの
\nは PHP の 改行文字に変換される - JSONの
\\nは\n(文字列)に変換される
MySQL の場合
※入力はPHPからPDOやEloquent ORMなどから挿入する際の入力を想定しています
| 入力 | 保存される内容 | 表示・取得時の扱い |
|---|---|---|
"1行目\n2行目" |
実際の改行文字 | 改行されて表示される |
"1行目\\n2行目" |
バックスラッシュ・n |
\nがそのまま表示される |
'1行目\n2行目' |
バックスラッシュ・n |
\nがそのまま表示される |
文字列リテラルを挿入する場合は、\n は改行として認識されず、そのままの文字列がDBに保存されます
よくあるユースケースと対処法
ユースケース1:改行として扱いたい
- フロント:
"1行目\n2行目"をJSONで送信する - PHP:そのまま
json_decode()でOK - DB:改行文字がそのまま保存される
ユースケース2: \n という文字列をそのまま保存したい
- フロント:
"1行目\n2行目"でJSONを送信 - PHP: そのまま
json_decode()すると\n→改行になってしまうので
str_replace("\n", '\\n', $text)で明示的な変換をかける - DB:
\nが文字列として保存される
おわりに
2つ目のユースケースの場合、表示上は改行させたいのであれば取得時に保存時と逆の変換をかける必要があるので、基本的には不難しいことを考えず改行のままDBに保存する1つ目のユースケースが良いと思います。
落ち着いて整理すれば、そんなに複雑な話ではなかったですね。