まず「郵便番号フォーマット」でやりたいことをはっきりさせる
業務で郵便番号を扱うとき、だいたいこんな状況になります。
ユーザー入力はバラバラです。
"1234567"
"123-4567"
"123−4567"(全角)
"123 4567"
でも、システムとしてはこうしたいはずです。
- DB には「統一された形」で保存したい
- 画面には「見やすい形(123-4567)」で表示したい
つまり、やりたいことは大きく分けて二つです。
1つ目は「余計なものを取り除いて数字だけにそろえること」。
2つ目は「その数字を 123-4567 の形に整えること」。
この二段構えを、PHP のユーティリティ関数としてきれいに分けて考えると、コードがとても分かりやすくなります。
ステップ1:郵便番号から「数字だけ」を取り出す
まずは「正規化」するのが超重要
いきなりハイフンを入れ直そうとするのではなく、
最初に「数字だけの状態」にそろえるのがとても大事です。
理由はシンプルで、入力がどんな形でも、後続の処理を同じ前提で書けるからです。
「数字だけにする」処理を一箇所に閉じ込めておけば、
他の場所で「全角かも」「ハイフンあるかも」と悩まなくて済みます。
全角数字を半角にしてから、数字以外を全部消す
PHP だと、こう書くのが定番です。
/**
* 郵便番号から数字だけを取り出す(全角数字・ハイフン・空白などを吸収)
*/
function normalizeZipDigits(string $zip): string
{
// 全角数字を半角に変換
$zip = mb_convert_kana($zip, 'n', 'UTF-8');
// 数字以外をすべて削除
$digits = preg_replace('/[^0-9]/', '', $zip);
return $digits;
}
PHPここでやっていることは二つです。
一つ目は mb_convert_kana($zip, 'n', 'UTF-8') で、全角数字を半角にそろえています。
ユーザーが「1234567」と入力しても、「1234567」に変換されます。
二つ目は preg_replace('/[^0-9]/', '', $zip) で、「数字以外の文字」を全部削除しています。
ハイフン、スペース、全角ハイフンなどはここで消えます。
この関数を通すと、次のように全部同じ結果になります。
echo normalizeZipDigits("1234567"); // 1234567
echo normalizeZipDigits("123-4567"); // 1234567
echo normalizeZipDigits("123−4567"); // 1234567
echo normalizeZipDigits("123 4567"); // 1234567
PHPここまで来れば、「あとは7桁の数字」として扱えるので、かなり楽になります。
ステップ2:数字列を「123-4567」の形に整える
桁数チェックをしながらフォーマットする
日本の郵便番号は基本的に「7桁」です。
なので、数字だけにしたあとで「7桁かどうか」を見て、7桁なら 3-4 に分ける、というのが基本形です。
/**
* 数字だけの郵便番号を 123-4567 形式にフォーマットする
*
* 7桁なら 3-4 に分割
* それ以外はそのまま返す(無理にフォーマットしない)
*/
function formatZipDigits(string $digits): string
{
if (strlen($digits) !== 7) {
// 想定外の桁数は、そのまま返す
return $digits;
}
return substr($digits, 0, 3) . '-' . substr($digits, 3, 4);
}
PHPここでのポイントは二つあります。
一つ目は、「7桁以外は無理にフォーマットしない」ことです。
桁数がおかしいものをそれっぽく整形してしまうと、バグの原因になります。
「おかしいものはおかしいまま」にしておいた方が、バリデーションで気づきやすいです。
二つ目は、「3桁」と「4桁」に素直に分けているだけ、というシンプルさです。
郵便番号のフォーマットは、電話番号ほど複雑ではないので、これで十分実用的です。
ステップ1+2をまとめた「郵便番号フォーマット」ユーティリティ
生の入力から、いきなり「123-4567」にしてくれる関数
実務では、「ユーザー入力をそのまま渡したら、いい感じに 123-4567 にしてほしい」という場面が多いので、さっきの二つをまとめた関数を用意しておくと便利です。
/**
* 郵便番号を 123-4567 形式にフォーマットする(生入力対応)
*
* 例:
* "1234567" → "123-4567"
* "123-4567" → "123-4567"
* "123−4567" → "123-4567"
* "123 4567" → "123-4567"
*/
function formatZip(string $raw): string
{
// 1. 数字だけに正規化
$digits = normalizeZipDigits($raw);
// 2. 7桁なら 3-4 に分割
return formatZipDigits($digits);
}
PHP使い方はとてもシンプルです。
echo formatZip("1234567"); // 123-4567
echo formatZip("123-4567"); // 123-4567
echo formatZip("123−4567"); // 123-4567
echo formatZip("123 4567"); // 123-4567
echo formatZip("12345"); // 12345(桁数がおかしいのでそのまま)
PHP呼び出し側は、「とりあえず formatZip() に通せば、人間が見やすい形になる」と覚えておけばOKです。
バリデーションと組み合わせるとさらに実務向きになる
「フォーマット」と「妥当性チェック」は分けて考える
フォーマットは「見た目を整える」だけで、「正しい郵便番号かどうか」は別問題です。
なので、バリデーション用の関数を別に用意しておくと、設計がきれいになります。
/**
* 郵便番号として妥当な形式かどうか(簡易チェック)
*
* ここでは「数字7桁ならOK」というルールにしている
*/
function isValidZip(string $raw): bool
{
$digits = normalizeZipDigits($raw);
return strlen($digits) === 7;
}
PHPこれを組み合わせると、例えばこう書けます。
$input = $_POST['zip'] ?? '';
if (!isValidZip($input)) {
$error = "郵便番号は数字7桁で入力してください。";
} else {
$normalized = normalizeZipDigits($input); // DB 保存用(数字だけ)
$display = formatZip($input); // 画面表示用(123-4567)
}
PHPここでの大事な考え方は、「保存用」と「表示用」を分けることです。
保存用は「数字だけ」にしておくと検索や比較がしやすく、
表示用は「123-4567」のように人間に優しい形にしておくと UX が良くなります。
実務での使いどころのイメージ
フォーム入力のとき
ユーザーが入力した郵便番号を、確認画面や完了画面で表示するときに、formatZip() を通しておくと、それだけで見た目が整います。
また、入力欄の初期値として DB に保存してある値を表示するときも、
DB には「数字だけ」を保存しておいて、表示時に formatZipDigits() を通す、というパターンが使えます。
CSV インポート・エクスポートのとき
外部システムとの連携で、郵便番号がバラバラな形式で入ってくることがあります。
そのときに、インポート時に normalizeZipDigits() を通しておけば、
システム内部では常に「数字だけ」で扱えるようになります。
逆に、エクスポート時には formatZipDigits() を通して「123-4567」にして出すと、
人間が見ても分かりやすい CSV になります。
まとめ:今日からの「郵便番号フォーマット」ユーティリティ
大事なポイントだけ、ぎゅっとまとめます。
郵便番号フォーマットは、いきなりハイフンをいじるのではなく、
一つ目に「数字だけに正規化する」。
二つ目に「7桁なら 3-4 に分けて 123-4567 にする」。
この二段構えで考えると、コードがとてもシンプルになります。
実装の核になるのは、この三つです。
function normalizeZipDigits(string $zip): string
{
$zip = mb_convert_kana($zip, 'n', 'UTF-8');
return preg_replace('/[^0-9]/', '', $zip);
}
function formatZipDigits(string $digits): string
{
if (strlen($digits) !== 7) {
return $digits;
}
return substr($digits, 0, 3) . '-' . substr($digits, 3, 4);
}
function formatZip(string $raw): string
{
return formatZipDigits(normalizeZipDigits($raw));
}
PHP