PHP Tips | 文字列処理:フォーマット – 電話番号フォーマット

PHP PHP
スポンサーリンク

まず「電話番号フォーマット」でやりたいことをはっきりさせる

業務で電話番号を扱うとき、だいたいこんな問題が出てきます。

  • ユーザーが「ハイフンあり」「ハイフンなし」「スペース入り」などバラバラに入力してくる
  • DB には「統一された形」で保存したい
  • 画面表示では「見やすい形(ハイフン区切り)」にしたい

例えば、こんな入力が来るかもしれません。

"03-1234-5678"
"0312345678"
"03 1234 5678"
"03−1234−5678"(全角)

これらを、最終的にこうそろえたいわけです。

"03-1234-5678"

つまり、やりたいことは大きく分けて2つです。

  • 余計な文字(スペース・全角・記号)を取り除いて「数字だけ」にする
  • その数字を「ルールに従って」ハイフンで区切る

この2ステップを、PHP のユーティリティ関数としてまとめていきます。


ステップ1:電話番号から「数字だけ」を取り出す

まずは「正規化」するのが大事

いきなりハイフンを入れ直そうとするのではなく、
最初に「数字だけの状態」にそろえるのがとても重要です。

理由はシンプルで、

  • 入力が「03-1234-5678」か「0312345678」か「03 1234 5678」か
  • それをいちいち意識して処理を書くのはつらい

からです。

「一度、数字だけにしてしまう」ことで、
その後の処理をシンプルにできます。

正規表現で数字だけを抜き出す

PHP では、preg_replace を使って「数字以外を全部消す」という書き方ができます。

/**
 * 電話番号から数字だけを取り出す(全角数字も対応)
 */
function normalizePhoneDigits(string $phone): string
{
    // 全角数字を半角に変換
    $phone = mb_convert_kana($phone, 'n', 'UTF-8');

    // 数字以外をすべて削除
    $digits = preg_replace('/[^0-9]/', '', $phone);

    return $digits;
}
PHP

ここでやっていることは2つです。

  1. mb_convert_kana(..., 'n', ...) で「全角数字 → 半角数字」に変換
  2. preg_replace('/[^0-9]/', '', $phone) で「数字以外を全部削除」

これで、次のような入力はすべて同じ結果になります。

echo normalizePhoneDigits("03-1234-5678");      // 0312345678
echo normalizePhoneDigits("03 1234 5678");      // 0312345678
echo normalizePhoneDigits("03−1234−5678"); // 0312345678
PHP

この「数字だけにする」ステップを、必ず最初に通すのがポイントです。


ステップ2:数字列を「ハイフン付き電話番号」に整形する

まずはシンプルに「桁数だけで分ける」版

日本の電話番号は本当は「市外局番のパターン」によって区切り位置が変わりますが、
まずは初心者向けに「桁数だけでざっくり分ける」版からいきます。

よくあるパターンはこの2つです。

  • 固定電話:10桁(例:031234567803-1234-5678
  • 携帯電話:11桁(例:09012345678090-1234-5678

これをそのままコードにすると、こうなります。

/**
 * 数字だけの電話番号を、ハイフン付きにフォーマットする(簡易版)
 *
 * 10桁: XX-XXXX-XXXX
 * 11桁: XXX-XXXX-XXXX
 * それ以外: そのまま返す
 */
function formatPhoneSimple(string $digits): string
{
    $len = strlen($digits);

    if ($len === 10) {
        // 固定電話っぽい: 2-4-4 に分割
        return substr($digits, 0, 2) . '-' .
               substr($digits, 2, 4) . '-' .
               substr($digits, 6, 4);
    }

    if ($len === 11) {
        // 携帯っぽい: 3-4-4 に分割
        return substr($digits, 0, 3) . '-' .
               substr($digits, 3, 4) . '-' .
               substr($digits, 7, 4);
    }

    // 想定外の桁数は、そのまま返す
    return $digits;
}
PHP

使い方はこうです。

echo formatPhoneSimple("0312345678");   // 03-1234-5678
echo formatPhoneSimple("09012345678");  // 090-1234-5678
echo formatPhoneSimple("123456");       // 123456(そのまま)
PHP

ここでの重要ポイントは、

  • 「桁数でざっくり判定する」だけでも、かなり実務で役に立つ
  • 想定外の桁数は「無理にフォーマットせず、そのまま返す」方が安全

ということです。


ステップ1+2をまとめた「電話番号フォーマット」ユーティリティ

normalize → format の2段構えを1つの関数に

実務では、「生の入力」からいきなりフォーマットしたいことが多いので、
さっきの2つをまとめた関数を用意しておくと便利です。

/**
 * 電話番号を「ハイフン付き」の見やすい形式に整える(簡易版)
 *
 * 例:
 *   "03-1234-5678"      → "03-1234-5678"
 *   "0312345678"        → "03-1234-5678"
 *   "03 1234 5678" → "03-1234-5678"
 */
function formatPhone(string $raw): string
{
    // 1. 数字だけに正規化
    $digits = normalizePhoneDigits($raw);

    // 2. 桁数に応じてハイフンを入れる
    return formatPhoneSimple($digits);
}
PHP

使い方はとてもシンプルになります。

echo formatPhone("03-1234-5678");          // 03-1234-5678
echo formatPhone("0312345678");            // 03-1234-5678
echo formatPhone("03 1234 5678"); // 03-1234-5678
echo formatPhone("090-1234-5678");         // 090-1234-5678
PHP

呼び出し側は「とりあえず formatPhone() に通せば、
それなりにきれいな形になる」という感覚で使えます。


もう一歩踏み込む:市外局番パターンに応じたフォーマット(考え方だけ)

ここは少しレベル高めですが、考え方だけ触れておきます。

日本の固定電話の市外局番は、長さがバラバラです。

  • 2桁(例:03, 06)
  • 3桁(例:011, 052)
  • 4桁(例:0994 など一部地域)

本気でやるなら、「市外局番の一覧」を持っておいて、
それに応じて区切り位置を変える必要があります。

ざっくりした考え方はこうです。

  1. 数字だけに正規化する(さっきと同じ)
  2. 先頭から2桁・3桁・4桁を試しながら、「市外局番リスト」にあるか調べる
  3. 見つかった長さで市外局番を切り出し、残りを市内局番+加入者番号として分割する

ただ、これは「電話番号ライブラリ」の世界になってくるので、
業務アプリの中で自前で全部やろうとすると、かなり大変です。

多くの業務では、

  • 携帯は 3-4-4
  • 固定は 2-4-4(東京・大阪)か 3-3-4(それ以外)くらいのざっくりルール

で十分なことも多いので、
「どこまでやるか」はプロジェクトの要求次第で決めるのが現実的です。


実務での使いどころ

DB 保存用と表示用を分ける

よくある設計はこうです。

  • DB には「数字だけ」を保存する(検索・比較がしやすい)
  • 画面表示のときだけ「フォーマット済み」を使う

その場合のイメージコードはこんな感じです。

// 保存時
$rawInput   = $_POST['phone'] ?? '';
$digitsOnly = normalizePhoneDigits($rawInput);
// $digitsOnly を DB に保存する

// 表示時
$storedDigits = $row['phone']; // DB から取得した数字だけの電話番号
$displayPhone = formatPhoneSimple($storedDigits);
// 画面には $displayPhone を出す
PHP

こうしておくと、

  • DB 内は常に「きれいな数字だけ」
  • 表示は「人間に優しいハイフン付き」

という状態を保てます。

バリデーションとの組み合わせ

フォーマットと一緒に、「電話番号として妥当かどうか」もチェックしたい場合は、
「数字だけにしたあと、桁数をチェックする」という流れにするとシンプルです。

function isValidPhone(string $raw): bool
{
    $digits = normalizePhoneDigits($raw);
    $len    = strlen($digits);

    // ここでは「10桁か11桁ならOK」という簡易ルールにしておく
    return $len === 10 || $len === 11;
}
PHP

フォーマットとバリデーションを分けておくと、
「見た目」と「正しさ」を別々に考えられるので、コードが整理しやすくなります。


まとめ:今日からの「電話番号フォーマット」ユーティリティ

押さえておきたいポイントだけ、ぎゅっとまとめます。

  • いきなりハイフンをいじるのではなく、まず「数字だけ」に正規化するのが超重要。
  • mb_convert_kana(..., 'n', ...) で全角数字を半角に、preg_replace('/[^0-9]/', '', ...) で数字以外を削除する。
  • 10桁・11桁だけでも、「2-4-4」「3-4-4」に分ける簡易フォーマットは実務でかなり役に立つ。
  • 保存用(数字だけ)と表示用(フォーマット済み)を分ける設計にすると、後々楽になる。

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