PHP Tips | 文字列処理:基本操作 – 改行コードを LF に統一

PHP PHP
スポンサーリンク

「改行コードを 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」になってしまいます。
だから必ず、

  1. まず "\r\n""\n"
  2. そのあとで単独の "\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 向けのテキストファイルを生成したい場合などです。

その場合は、

  1. まず「どんな入力でも LF に統一」
  2. 最後に「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レスポンス、メール本文、ログ解析など)に、
まずこの関数を一段かませるだけで、「改行コードの違い」による不具合をかなり減らせます。

タイトルとURLをコピーしました