PHP Tips | 文字列処理:文字数・切り出し – 固定長になるよう左パディング

PHP PHP
スポンサーリンク

「固定長になるよう左パディング」とは何か

イメージとしてはこうです。

文字列を「決まった長さ」にそろえるために、
足りない分を左側に 0 やスペースで埋めること。

特に「数値っぽい項目」でよく使います。

1      → 000001
123   → 000123
99999 → 099999

桁数をそろえることで、
ログや帳票、固定長ファイル、外部システム連携などで扱いやすくなります。


PHP の基本:str_pad で左パディング

str_pad の基本形と左パディング

PHP の str_pad() は、左右・中央へのパディングをまとめて扱える関数です。

string str_pad(
    string $string,
    int $length,
    string $pad_string = " ",
    int $pad_type = STR_PAD_RIGHT
)
PHP

左パディングをしたいときは、第4引数に STR_PAD_LEFT を指定します。

$value = "123";

$padded = str_pad($value, 6, '0', STR_PAD_LEFT);

echo $padded;  // 000123
PHP

ここでの意味はこうです。

  • 元の文字列:"123"
  • 最終的な長さ:6
  • 埋める文字:'0'
  • 左側を埋める:STR_PAD_LEFT

結果として、「左側に 0 を足して 6桁にそろえる」動きになります。

スペースで左パディングする例

数値ではなく、文字列を右寄せしたいときはスペースで埋めます。

$name = "Taro";

$padded = str_pad($name, 10, ' ', STR_PAD_LEFT);

echo '[' . $padded . ']';
// [      Taro]
PHP

「Taro」は 4文字なので、左側にスペースが 6個足されて、全体で 10文字になります。


重要ポイント:str_pad は「バイト数」で長さを見る

日本語を混ぜるとズレる理由

str_pad は「文字数」ではなく「バイト数」で長さを見ています。

$name = "太郎"; // UTF-8

echo strlen($name);  // 6(1文字3バイト×2文字)
PHP

この状態で、こう書くとします。

$name = "太郎";

$padded = str_pad($name, 10, ' ', STR_PAD_LEFT);

echo '[' . $padded . ']';
PHP

str_pad の「10」は「10バイト」の意味です。

  • 「太郎」:6バイト
  • 足りない分:4バイト → スペース4個

結果として、バイト数としては 10 になりますが、
見た目の文字数としては「スペース4+太郎2」で 6文字にしか見えません。

画面上の「見た目をそろえたい」目的で使うと、
全角・半角が混ざったときにきれいにそろわない、という問題が出ます。

いつ「バイト数」でよくて、いつダメか

整理するとこうです。

  • 固定長ファイル、外部システム連携など「バイト数で長さが決まっている」場面
    str_pad の長さ指定はそのまま使ってよい
  • 画面表示で「見た目の幅」をそろえたい場面
    → 別のアプローチ(mb_strwidth など)が必要

ここからは、実務でよく使う「バイト数前提の左パディング」をユーティリティとしてまとめていきます。


実務ユーティリティ:バイト数前提の左パディング

固定長ファイルや外部連携で使う形

仕様例:

  • 顧客IDは 8バイト
  • 足りない分は左側を 0 で埋める
  • UTF-8 だが、IDは基本的に数字のみ

こういうときに使えるユーティリティを作ります。

/**
 * 固定長出力用:バイト数ベースで左パディング(UTF-8 前提)
 *
 * @param string $text      元の文字列
 * @param int    $byteWidth 最終的なバイト長
 * @param string $padChar   埋める文字(1バイト文字を推奨:'0' や ' ' など)
 * @return string
 */
function leftPadBytes(string $text, int $byteWidth, string $padChar = '0'): string
{
    // まず、バイト数が多すぎる場合は切り詰める(mb_strcut で途中で文字を壊さない)
    $cut = mb_strcut($text, 0, $byteWidth, 'UTF-8');

    // そのうえで、足りない分を左側にパディング
    return str_pad($cut, $byteWidth, $padChar, STR_PAD_LEFT);
}
PHP

使い方の例

$id = "123";

echo leftPadBytes($id, 8, '0');   // 00000123

$id2 = "9999999999";              // 10バイト相当

echo leftPadBytes($id2, 8, '0');  // 先頭から8バイトに切られて出力
PHP

ここでのポイントは2つです。

  • mb_strcut で「バイト数で切るが、マルチバイト文字の途中では切らない」
  • そのあと str_pad で「バイト数ベースで左パディング」

これで、「最大バイト数を超えない」「足りない分は左側を埋める」という仕様を、安全に満たせます。


例題でイメージを固める

例題1:固定長ファイルの数値項目

仕様:

  • 金額フィールドは 10バイト
  • 左側を 0 で埋める
  • 小数点なしの整数文字列として扱う
$amount = "12345";

$field = leftPadBytes($amount, 10, '0');

echo $field;  // 0000012345
PHP

この field を、そのまま固定長ファイルの一部として書き出せます。

例題2:ログの番号をそろえる

for ($i = 1; $i <= 12; $i++) {
    $no = leftPadBytes((string)$i, 4, '0');
    echo "[{$no}] ログメッセージ" . PHP_EOL;
}
PHP

出力イメージ:

[0001] ログメッセージ
[0002] ログメッセージ
...
[0012] ログメッセージ

番号がきれいにそろうので、ログを目で追いやすくなります。


「見た目の幅」をそろえる左パディング(おまけ)

画面表示で「右寄せしたい」だけなら、
「バイト数」ではなく「表示幅(全角2・半角1)」を使う方が自然です。

mb_strwidth() を使うと、表示幅を計算できます。

echo mb_strwidth("ABC", 'UTF-8');   // 3
echo mb_strwidth("太郎", 'UTF-8');  // 4
PHP

これを使った左パディングは、こんな感じで書けます。

/**
 * 表示幅ベースで左パディング(全角2・半角1として計算)
 */
function leftPadDisplayWidth(string $text, int $width, string $padChar = ' '): string
{
    $currentWidth = mb_strwidth($text, 'UTF-8');

    if ($currentWidth >= $width) {
        return $text;
    }

    $padCount = $width - $currentWidth;

    return str_repeat($padChar, $padCount) . $text;
}
PHP

これは「画面表示用」のユーティリティとして覚えておくと便利です。


まとめ:今日からの「左パディング」の基準

押さえておきたいポイントを整理します。

  • str_pad は「バイト数ベース」で長さを見ている。
  • 固定長ファイルや外部仕様など「バイト数」が決まっている場面では、str_pad を素直に使ってよい。
  • 日本語を含む可能性があるなら、まず mb_strcut でバイト数を制限し、そのあと str_pad で左パディングするのが安全。
  • 画面の「見た目の幅」をそろえたいときは、mb_strwidth を使った別ユーティリティ(表示幅ベース)を用意する。

実務ユーティリティとしては、まずはこれ一つをプロジェクトに置いておくとかなり役に立ちます。

function leftPadBytes(string $text, int $byteWidth, string $padChar = '0'): string
{
    $cut = mb_strcut($text, 0, $byteWidth, 'UTF-8');
    return str_pad($cut, $byteWidth, $padChar, STR_PAD_LEFT);
}
PHP

タイトルとURLをコピーしました