まず「電話番号フォーマット」でやりたいことをはっきりさせる
業務で電話番号を扱うとき、だいたいこんな問題が出てきます。
- ユーザーが「ハイフンあり」「ハイフンなし」「スペース入り」などバラバラに入力してくる
- 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つです。
mb_convert_kana(..., 'n', ...)で「全角数字 → 半角数字」に変換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桁(例:
0312345678→03-1234-5678) - 携帯電話:11桁(例:
09012345678→090-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 など一部地域)
本気でやるなら、「市外局番の一覧」を持っておいて、
それに応じて区切り位置を変える必要があります。
ざっくりした考え方はこうです。
- 数字だけに正規化する(さっきと同じ)
- 先頭から2桁・3桁・4桁を試しながら、「市外局番リスト」にあるか調べる
- 見つかった長さで市外局番を切り出し、残りを市内局番+加入者番号として分割する
ただ、これは「電話番号ライブラリ」の世界になってくるので、
業務アプリの中で自前で全部やろうとすると、かなり大変です。
多くの業務では、
- 携帯は 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」に分ける簡易フォーマットは実務でかなり役に立つ。
- 保存用(数字だけ)と表示用(フォーマット済み)を分ける設計にすると、後々楽になる。

