「改行コードを LF に統一」とは何か
PHP で文字列やファイルを扱うとき、「改行」が入っていることはよくあります。
でも、実は「改行」と一口に言っても、環境によって使われる「改行コード」が違います。
代表的なものは次の3つです。
LF : \n (Unix / Linux / macOS)
CRLF : \r\n (Windows)
CR : \r (古い Mac)
見た目はどれも「行が変わっている」ように見えますが、内部的には別の文字列です。
この違いが原因で、「同じファイルのはずなのに動きが変わる」「文字列比較で一致しない」といったトラブルが起きます。
そこでやりたいのが、
どんな改行コードが混ざっていても、いったん全部「LF(
\n)」にそろえる
という処理です。
なぜ改行コードを LF に統一する必要があるのか
OS やツールによって改行コードがバラバラになるから
例えば、次のような状況を想像してみてください。
Windows のエディタで作ったテキストファイル(CRLF)を、Linux サーバー上の PHP で読み込む。
あるいは、外部システムから送られてきたデータが、環境によって CRLF だったり LF だったりする。
PHP の文字列として見たとき、これらは別物です。
$text1 = "A\nB"; // LF
$text2 = "A\r\nB"; // CRLF
var_dump($text1 === $text2); // bool(false)
PHP見た目は同じ「2行のテキスト」でも、プログラム的には違う文字列です。
この違いを放置しておくと、比較・置換・分割などの処理が不安定になります。
だからこそ、
「まず最初に改行コードを自分の基準(ここでは LF)にそろえる」
というのが、実務でとても大事な一手になります。
改行で分割するときに安定させたいから
例えば、「1行ごとに処理したい」というコードを書くとします。
$lines = explode("\n", $text);
PHPこのとき、もし $text の中に CRLF(\r\n)が混ざっていると、行末に \r が残ってしまいます。
$text = "A\r\nB\r\n";
$lines = explode("\n", $text);
var_dump($lines);
/*
array(3) {
[0] =>
string(2) "A\r"
[1] =>
string(2) "B\r"
[2] =>
string(0) ""
}
*/
PHP行末に \r が残っていると、比較や表示で微妙な不具合が出ます。
最初に改行コードを LF に統一しておけば、こうした「見えないゴミ」が混ざる問題を避けられます。
PHP で改行コードを LF に統一する基本パターン
一番よく使う書き方:str_replace を2回使う
改行コードを LF に統一する、シンプルで実務的な書き方はこれです。
function normalizeNewlineToLF(string $text): string
{
// 1. まず CRLF(\r\n)を LF(\n)に変換
$text = str_replace("\r\n", "\n", $text);
// 2. 次に、残っている CR(\r)を LF(\n)に変換
$text = str_replace("\r", "\n", $text);
return $text;
}
PHPこの順番がとても重要です。
先に "\r" を "\n" に置き換えてしまうと、CRLF(\r\n)が「\n\n」になってしまいます。
だから必ず、
- まず
"\r\n"を"\n"に - そのあとで単独の
"\r"を"\n"に
という順番で置き換えます。
この関数を通せば、どんな改行コードが混ざっていても、最終的にはすべて LF(\n)にそろえることができます。
実務での具体的なシチュエーション例
例題1:アップロードされたテキストファイルの改行をそろえる
ユーザーがアップロードしたテキストファイルを処理するケースを考えます。
Windows で作られたファイルは CRLF、Linux で作られたファイルは LF になっていることが多いです。
$contents = file_get_contents($uploadedFilePath);
// 改行コードを LF に統一
$contents = normalizeNewlineToLF($contents);
// 1行ごとに処理
$lines = explode("\n", $contents);
foreach ($lines as $line) {
// ここでは、行末に余計な \r が残らない
// 行ごとの処理を書く
}
PHPこのように、「ファイルを読み込んだ直後」に改行コードを統一しておくと、その後の処理がとてもシンプルになります。
例題2:外部 API から受け取ったテキストを行単位で扱う
外部 API から、複数行のテキストが返ってくることがあります。
その API がどの OS で動いているかによって、改行コードが変わる可能性があります。
$responseBody = $client->get(...); // 仮のコード
$text = $responseBody['message'] ?? '';
// 改行コードを LF に統一
$text = normalizeNewlineToLF($text);
// 行ごとに配列にする
$lines = explode("\n", $text);
PHPこうしておけば、「API 側の環境に依存しない」安定した処理が書けます。
例題3:テンプレート文字列の改行をそろえて比較する
例えば、「メールテンプレート」と「実際に送信した本文」を比較したい、というようなケースを考えます。
テンプレートは Linux 上で作られたファイル(LF)、
実際の本文は Windows のエディタで編集されたもの(CRLF)かもしれません。
$template = file_get_contents('template.txt');
$body = getMailBodyFromSomewhere();
// どちらも LF に統一してから比較する
$template = normalizeNewlineToLF($template);
$body = normalizeNewlineToLF($body);
var_dump($template === $body);
PHP改行コードをそろえずに比較すると、「内容は同じなのに一致しない」ということが起きます。
LF に統一してから比較することで、「本当に内容が同じかどうか」を正しく判定できます。
重要ポイントの深掘り
「改行コードの違い」は目に見えないバグの温床
初心者のうちは、画面に表示される見た目だけを見てしまいがちですが、
プログラムにとっては「\n と \r\n は別物」です。
例えば、次のようなコードを見てください。
$text = "A\r\nB";
echo nl2br($text);
PHPブラウザで見ると、ちゃんと2行に見えるかもしれません。
でも、内部的には "\r\n" が入っているので、explode("\n", $text) で分割すると、行末に \r が残ります。
この「見た目では分からない違い」が、ログ解析、差分比較、テストコードなどでじわじわ効いてきます。
だからこそ、「改行コードをまず統一する」というのは、実務での安定運用のための基本テクニックになります。
「どのタイミングで LF に統一するか」を決める
改行コードを LF に統一するタイミングは、主に次のどこかになります。
外部からデータを受け取った直後(ファイル、API、フォームなど)。
内部で文字列を組み立てるときは LF を前提にする。
保存前や比較前に、念のためもう一度統一する。
初心者のうちは、まずは次のルールを自分の中で決めてしまうと楽です。
「外から入ってきた複数行テキストは、最初に必ず normalizeNewlineToLF を通す」
これだけで、改行コードに起因するバグのかなりの部分を潰せます。
応用:LF に統一したあと、必要なら別の改行コードに変換する
システムによっては、「内部では LF で扱いたいけれど、最終的には CRLF で出力したい」ということもあります。
例えば、Windows 向けのテキストファイルを生成したい場合などです。
その場合は、
- まず「どんな入力でも LF に統一」
- 最後に「LF を CRLF に変換」
という二段構えにすると、ロジックがきれいになります。
function normalizeNewlineToLF(string $text): string
{
$text = str_replace("\r\n", "\n", $text);
$text = str_replace("\r", "\n", $text);
return $text;
}
function convertLFToCRLF(string $text): string
{
// いったん LF に統一されている前提で、LF を CRLF に変換
return str_replace("\n", "\r\n", $text);
}
// 例:内部処理
$text = file_get_contents('input.txt');
$text = normalizeNewlineToLF($text);
// ここでいろいろ処理する
// Windows 向けに出力したいとき
$output = convertLFToCRLF($text);
file_put_contents('output.txt', $output);
PHP「内部表現は LF に統一」「外部とのやり取りのときだけ変換」という設計にしておくと、
システム全体の見通しがとても良くなります。
まとめ:今日から使える「改行コードを LF に統一」テンプレ
実務でそのまま使える、改行コード統一の基本関数をもう一度まとめておきます。
function normalizeNewlineToLF(string $text): string
{
// 1. CRLF を LF に
$text = str_replace("\r\n", "\n", $text);
// 2. 残っている CR を LF に
$text = str_replace("\r", "\n", $text);
return $text;
}
PHP複数行の文字列を扱うところ(ファイル読み込み、APIレスポンス、メール本文、ログ解析など)に、
まずこの関数を一段かませるだけで、「改行コードの違い」による不具合をかなり減らせます。
