「表示用マスク(電話)」で何を守りたいのか
電話番号もメールと同じく、個人をかなり特定できる情報です。
でも業務では、こういうニーズがよく出てきます。
誰のレコードかは判別したい。
ログや画面には「丸裸の番号」は出したくない。
そこで、「電話番号を一部だけ見せて、残りをマスクする」表示用マスクを用意します。
090-1234-5678 → 090-****-567803-1234-5678 → 03-****-5678
本人や運用者には「だいたい誰か分かる」けれど、
第三者にとってはフルの番号が分からない、という状態を作るのが目的です。
まず「数字だけ」にそろえる、という前処理
電話番号は、いろいろな書き方をされます。
09012345678090-1234-5678(090) 1234-5678090−1234−5678
マスク処理をシンプルにするために、まずは「数字だけ」にそろえます。
function normalize_phone_digits(string $phone): string
{
// 全角数字を半角に
$phone = mb_convert_kana($phone, 'n', 'UTF-8');
// 数字以外を全部削除
return preg_replace('/\D+/', '', $phone) ?? '';
}
PHPこれで、どんな書き方でも最終的にこうなります。
normalize_phone_digits('090-1234-5678') → 09012345678normalize_phone_digits('03−1234−5678') → 0312345678
この「数字だけの電話番号」をベースにマスクを考えます。
マスクの方針を決める
ここでは、シンプルにこう決めます。
桁数が短い(4 桁以下)なら、そのまま(内線などを想定)。
それ以上なら、「先頭数桁」と「末尾 4 桁」だけ見せて、間を * で埋める。
日本の電話番号をざっくりイメージすると、
携帯:11 桁(090xxxxxxxx)
固定:10 桁(03xxxxxxxx, 045xxxxxxx など)
なので、例えばこういう感じにします。
09012345678 → 090****56780312345678 → 03****5678
「先頭 2〜3 桁」と「末尾 4 桁」が見えていれば、
誰の番号かはだいたい分かるけれど、真ん中は隠せます。
コアとなるマスク関数を作る
function mask_phone_for_display(string $phone): string
{
$digits = normalize_phone_digits($phone);
$len = strlen($digits);
// 桁数が少なすぎる場合は、そのまま返す(内線など)
if ($len <= 4) {
return $digits;
}
// 先頭を何桁見せるか(携帯なら 3、固定なら 2 を想定)
if ($len === 11) {
$headLen = 3; // 090 / 080 / 070 など
} else {
$headLen = 2; // 03 / 06 / 04 など
}
// 末尾は 4 桁見せる
$tailLen = 4;
// 万が一、長さが足りない場合の保険
if ($headLen + $tailLen >= $len) {
// そのまま返すか、簡易マスクにするかは運用次第
return $digits;
}
$head = substr($digits, 0, $headLen);
$tail = substr($digits, -$tailLen);
$maskCount = $len - $headLen - $tailLen;
$mask = str_repeat('*', $maskCount);
return $head . $mask . $tail;
}
PHPここでは「数字だけの文字列」を返していますが、
必要なら後で 090-****-5678 のようにハイフンを挿入することもできます。
例題で挙動を確認する
携帯番号の例
echo mask_phone_for_display('090-1234-5678');
// 090****5678
echo mask_phone_for_display('08012345678');
// 080****5678
PHP先頭 3 桁(キャリア識別)と末尾 4 桁(個人識別)だけ見せて、
真ん中 4 桁を **** にしています。
固定電話の例
echo mask_phone_for_display('03-1234-5678');
// 03****5678
echo mask_phone_for_display('045-123-4567');
// 04***4567
PHP固定電話は桁構成がいろいろありますが、
ここでは「先頭 2 桁+末尾 4 桁」を見せるシンプルなルールにしています。
短い番号(内線など)の例
echo mask_phone_for_display('1234');
// 1234
echo mask_phone_for_display('12');
// 12
PHP4 桁以下はそのまま返すようにしているので、
内線番号などはマスクせずに扱えます(ここは運用ポリシー次第で変えてOKです)。
ログ・画面での使いどころ
ログ出力時
$rawPhone = $_POST['phone'] ?? '';
$masked = mask_phone_for_display($rawPhone);
error_log('SMS send failed to phone=' . $masked);
PHPログには「どの番号に送ろうとしたか」が分かる形で残りつつ、
フルの番号は見えません。
管理画面の一覧表示
<td><?= htmlspecialchars(mask_phone_for_display($user['phone']), ENT_QUOTES, 'UTF-8') ?></td>
PHPサポート担当は「だいたい誰の番号か」を把握できますが、
画面をチラ見した第三者にはフルの番号は分かりません。
どこまでマスクするかは「メールと同じくポリシー次第」
今回の実装はあくまで「一例」です。
実務では、次のようなバリエーションもありえます。
末尾 4 桁も隠して、先頭だけ見せる。
携帯はより厳しくマスクする。
そもそも電話番号はログに出さない。
大事なのは、「マスクルールを 1 箇所(ユーティリティ関数)に閉じ込める」ことです。
そうしておけば、ポリシー変更があっても、その関数だけ直せば全体に反映できます。
まとめ:今日からの「表示用マスク(電話)」ユーティリティ
表示用マスク(電話)の目的は、「運用上の識別はできるが、フルの番号は見せない」ことです。
そのために、
まず電話番号を「数字だけ」に正規化する。
桁数に応じて、「先頭数桁+末尾 4 桁」だけ見せて、間を * で埋める。
ログや画面では、必ずこの関数を通した値だけを使う。
というルールを徹底します。
もう一度、コア部分をまとめておきます。
function normalize_phone_digits(string $phone): string
{
$phone = mb_convert_kana($phone, 'n', 'UTF-8');
return preg_replace('/\D+/', '', $phone) ?? '';
}
function mask_phone_for_display(string $phone): string
{
$digits = normalize_phone_digits($phone);
$len = strlen($digits);
if ($len <= 4) {
return $digits;
}
$headLen = ($len === 11) ? 3 : 2;
$tailLen = 4;
if ($headLen + $tailLen >= $len) {
return $digits;
}
$head = substr($digits, 0, $headLen);
$tail = substr($digits, -$tailLen);
$mask = str_repeat('*', $len - $headLen - $tailLen);
return $head . $mask . $tail;
}
PHPもし、あなたのプロジェクトで「ログに生の電話番号を出している」「一覧画面にフルの番号を出している」箇所があれば、そこがこのユーティリティを差し込むベストポイントです。
その 1 行を差し替えるだけで、個人情報の“見せ方の質”が一段上がります。
