「表示用マスク(名前)」で何を守りたいのか
名前も、メールや電話と同じく「個人を特定しやすい情報」です。
でも業務では、こういうニーズがよく出てきます。
ログや通知には「誰の処理か」は分かりたい。
サポート画面では「対象ユーザーは分かるが、フルネームは隠したい」。
そこで使うのが「表示用マスク(名前)」です。
山田太郎 → 山田*郎佐藤花子 → 佐*花子Taro Yamada → T*** Y*****
「本人や運用者には誰か分かるけど、丸見えではない」状態を作るのが目的です。
まず「どうマスクするか」の方針を決める
日本語フルネームのざっくり方針
日本語の名前は、だいたい「姓+名」で構成されますが、
システム上は「姓」「名」が分かれている場合と、「フルネーム 1 本」の場合があります。
ここでは、まず「フルネーム 1 本の文字列」をマスクする方針を決めます。
文字数が 1 文字なら:そのまま(マスクしない)。
文字数が 2 文字なら:先頭 1 文字だけ残して、残りを *。
文字数が 3 文字以上なら:
先頭 1 文字と末尾 1 文字を残して、間を * で埋める。
例としてはこうなります。
山田 → 山*太郎 → 太*山田太郎 → 山田*郎佐藤花子 → 佐*花子
「完全には隠さないけど、全部は見せない」というバランスです。
コアとなるマスク関数を作る
フルネーム 1 本をマスクする関数
日本語を安全に扱うために、mb_strlen / mb_substr を使います。
function mask_name_for_display(string $name): string
{
$name = trim($name);
if ($name === '') {
return $name;
}
$len = mb_strlen($name, 'UTF-8');
if ($len === 1) {
// 1 文字はそのまま
return $name;
}
if ($len === 2) {
// 2 文字なら先頭だけ残す
$head = mb_substr($name, 0, 1, 'UTF-8');
return $head . '*';
}
// 3 文字以上なら、先頭と末尾を残して間をマスク
$head = mb_substr($name, 0, 1, 'UTF-8');
$tail = mb_substr($name, -1, 1, 'UTF-8');
$maskCount = $len - 2;
$mask = str_repeat('*', $maskCount);
return $head . $mask . $tail;
}
PHPここでは、マスク文字に全角の * を使っています(日本語 UI でよく使われるため)。
半角 * を使いたければ、そこだけ変えれば OK です。
例題で挙動を確認する
日本語の例
echo mask_name_for_display('山田'); // 山*
echo mask_name_for_display('太郎'); // 太*
echo mask_name_for_display('山田太郎'); // 山**郎
echo mask_name_for_display('佐藤花子'); // 佐**子
PHP3 文字以上の場合、「真ん中全部がマスク」されるので、
姓+名がくっついていても、だいたいの雰囲気だけが残ります。
英字名の例
echo mask_name_for_display('Taro'); // T**o
echo mask_name_for_display('Yamada'); // Y***a
echo mask_name_for_display('Taro Yamada'); // T******a
PHPスペースも 1 文字としてカウントされるので、
「フルネーム全体を 1 つの文字列としてマスク」する挙動になります。
英字名をもう少し丁寧に扱いたい場合は、「スペースで分割して、単語ごとにマスクする」という発展形も作れます。
「姓」「名」が分かれている場合のマスク
姓と名を別々にマスクしてから結合する
多くの業務システムでは、「姓」「名」が別カラムになっていることが多いです。
$lastName = '山田';
$firstName = '太郎';
PHPこの場合は、それぞれにマスクをかけてから結合するのが分かりやすいです。
$maskedFullName = mask_name_for_display($lastName) . ' ' . mask_name_for_display($firstName);
echo $maskedFullName; // 山* 太*
PHP姓と名を別々にマスクすることで、「どちらの情報も少しだけ見える」状態になります。
サポート画面などでは、このほうが「誰か」を特定しやすいことが多いです。
実務での使いどころ
ログ出力時のマスク
$rawName = $user['name'] ?? '';
$masked = mask_name_for_display($rawName);
error_log('Password reset requested by name=' . $masked);
PHPログには「どのユーザーか」が分かる形で残りつつ、
フルネームは見えません。
管理画面の一覧表示
<td><?= htmlspecialchars(mask_name_for_display($user['name']), ENT_QUOTES, 'UTF-8') ?></td>
PHPサポート担当は「だいたい誰か」を把握できますが、
画面をチラ見した第三者にはフルの名前は分かりません。
どこまでマスクするかは「ポリシー」で決める
今回のルールはあくまで「一例」です。
実務では、次のようなバリエーションもありえます。
1 文字でも必ずマスクする(山 → *)。
姓はフル表示、名だけマスクする。
外国人名は別ルールにする。
大事なのは、「マスクルールを 1 箇所(ユーティリティ関数)に閉じ込める」ことです。
そうしておけば、ポリシー変更があっても、その関数だけ直せば全体に反映できます。
まとめ:今日からの「表示用マスク(名前)」ユーティリティ
表示用マスク(名前)の目的は、「運用上の識別はできるが、フルネームは見せない」ことです。
そのために、
名前の長さに応じて「一部だけ残し、残りをマスク文字に置き換える」。
ログや画面では、必ずこの関数を通した値だけを使う。
というルールを徹底します。
もう一度、コア関数を載せておきます。
function mask_name_for_display(string $name): string
{
$name = trim($name);
if ($name === '') {
return $name;
}
$len = mb_strlen($name, 'UTF-8');
if ($len === 1) {
return $name;
}
if ($len === 2) {
$head = mb_substr($name, 0, 1, 'UTF-8');
return $head . '*';
}
$head = mb_substr($name, 0, 1, 'UTF-8');
$tail = mb_substr($name, -1, 1, 'UTF-8');
$maskCount = $len - 2;
$mask = str_repeat('*', $maskCount);
return $head . $mask . $tail;
}
PHPもし、あなたのプロジェクトで「ログや一覧に生の氏名をそのまま出している」箇所があれば、そこがこのユーティリティを差し込むベストポイントです。
その 1 行を差し替えるだけで、「個人情報の見せ方」のレベルが一段上がります。
