💡 今日の3行まとめ
  • 数値を指定桁数のゼロ埋め(00042)にするなら if 文での文字連結は使わない
  • プレフィックスや年号を含む複合フォーマットには sprintf('MEM-%d-%05d', ...) が最適
  • 単一の文字列や数字の左側に文字を埋めるだけなら str_pad() で直感的に書ける

1. 今日のお題とゴール

会員登録の連番ID(7 や 42 など)と登録年(2026)を組み合わせて、5桁でゼロ埋めされた会員番号(MEM-2026-00042)を一覧出力するプログラムを作ります。

  • 連番IDの配列 $memberIds を5桁のゼロ埋め(00007〜)に揃える
  • MEM-西暦-5桁ID の書式にフォーマットして出力する
  • 5桁を超えるID(123456)が来ても桁落ちせずそのまま表示する
// 期待する出力例
MEM-2026-00007
MEM-2026-00042
MEM-2026-01050
MEM-2026-123456

2. ❌ やりがちなNGコード vs ⭕ コピペで動く正解コード

❌ やりがちなNGコードBefore
<?php
$id = 42;
if ($id < 10) {
    $padded = '0000' . $id;
} elseif ($id < 100) {
    $padded = '000' . $id;
} elseif ($id < 1000) {
    $padded = '00' . $id;
}
$code = 'MEM-2026-' . $padded; // 1000以上のとき未定義エラーに!

桁数ごとに if 文で '0' をつなぐと条件分岐だらけになり、想定外の桁数が来たときに変数が未定義になるバグや、桁数変更時の修正漏れを招きます。

⭕ コピペで動く正解コード(PHP 8.3+)After
<?php
declare(strict_types=1);

$year = 2026;
$memberIds = [7, 42, 1050, 123456];

// パターンA: sprintf() で書式テンプレートに流し込む(複合フォーマットに最適)
foreach ($memberIds as $id) {
    // %d = 整数(年)、%05d = 5桁に満たない左側を 0 で埋める整数
    $code = sprintf('MEM-%d-%05d', $year, $id);
    echo $code . PHP_EOL;
}

// パターンB: str_pad() で単一の値をゼロ埋めする(シンプルな桁揃えに便利)
$singleId = 42;
$paddedId = str_pad((string)$singleId, 5, '0', STR_PAD_LEFT);
echo "単体ゼロ埋め: {$paddedId}" . PHP_EOL; // 00042

3. ここだけ押さえる!3つのポイント

1sprintf の「%05d」は「0で埋める5桁の整数」

書式指定子の %05d は「0(埋める文字)+ 5(最小桁数)+ d(10進数の整数)」という意味です。MEM-%d-%05d のように固定文字と変数を1つのテンプレートにまとめられるため、文字列連結(.)が不要になります。

2str_pad() は第1引数を (string) にキャストする

str_pad() は文字列専用の関数のため、declare(strict_types=1); 環境で整数をそのまま渡すと TypeError になります。必ず (string)$singleId で文字列に変換し、第4引数に STR_PAD_LEFT(左側を埋める)を指定しましょう。

3指定桁数を超えても勝手に切り捨てられない

%05d や str_pad(..., 5, ...) に6桁の 123456 を渡しても、末尾が削られることはなく 123456 のまま安全に出力されます。あくまで「5桁未満のときに足りない分だけ埋める」動作なので、将来会員数が増えてもデータが壊れません。

4. 1分ミニチャレンジ

🚀 手を動かしてみよう

正解コードの sprintf('MEM-%d-%05d', $year, $id) の %05d を、%08d(8桁ゼロ埋め)や %05X(大文字16進数の5桁ゼロ埋め)に書き換えて実行してみましょう。書式指定子を少し変えるだけで、シリアルコード風の出力に一瞬で変わる感覚を体験できます。