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

PHP PHP
スポンサーリンク

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

まずイメージからいきましょう。

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

これが「右パディング」です。

例えば、外部システムに「名前は 10文字分の領域」と決められているとします。

Taro      (10文字分)
Hanako    (10文字分)

短い名前でも、右側にスペースを足して「固定長」にそろえる——
これが実務でよく出てくるパターンです。


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

よく使うのはこの形です。

  • 第1引数:元の文字列
  • 第2引数:最終的な長さ
  • 第3引数:埋める文字(省略時はスペース)
  • 第4引数:埋める方向(右なら STR_PAD_RIGHT

右側をスペースで埋める例

$name = "Taro";

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

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

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

右側を 0 で埋める例(数値っぽい文字列)

$code = "123";

$padded = str_pad($code, 6, '0', STR_PAD_RIGHT);

echo $padded;
// 123000
PHP

右側に 0 を足して「123000」のようにすることもできます。
(左側を 0 で埋めたいときは STR_PAD_LEFT です)


ここが重要:str_pad は「バイト数」で長さを見ている

日本語を混ぜるとズレる

問題はここからです。
str_pad は「バイト数」で長さを見ます。

$name = "太郎"; // UTF-8(1文字3バイトのことが多い)

echo strlen($name);  // 6(バイト数)
PHP

この状態で、こう書くとどうなるか。

$name = "太郎";

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

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

str_pad の「10」は「10バイト」の意味です。
「太郎」は 6バイトなので、あと 4バイト分スペースが足されます。

でも、画面上の「見た目の文字数」としては、

  • 「太郎」:2文字
  • スペース:2文字分

合計 4文字にしか見えません。

「固定長 10文字にそろえたつもりが、見た目は全然そろっていない」

ということが起きます。

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

ここを整理しておくと迷いません。

  • 外部仕様が「バイト数」で決まっている(固定長ファイル、古いプロトコルなど)
    str_pad の「長さ」はバイト数としてちょうどよい
  • 画面上の「見た目の幅」をそろえたい(一覧表示など)
    → マルチバイト文字を考慮した別アプローチが必要

今回の「業務・実務で使えるユーティリティ」としては、
どちらのパターンも意識しておく価値があります。


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

固定長ファイルや外部連携向け

「この項目は 20バイトで送ってください」と仕様に書かれているようなケースでは、
str_pad を素直に使うのが正解です。

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

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

使い方はこうです。

$name = "太郎";

echo '[' . rightPadBytes($name, 10, ' ') . ']';
PHP

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

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

これで、「10バイト以内に収める」「足りない分は右側を埋める」という仕様を、
日本語を壊さずに満たせます。


実務ユーティリティ2:見た目の幅をそろえる右パディング(おまけ)

「表示上の幅」をそろえたい場合

画面の一覧で「名前の列をきれいにそろえたい」といった場合は、
「バイト数」ではなく「表示幅(全角は2、半角は1)」を意識したくなります。

PHP には mb_strwidth() という関数があり、
「表示幅」を計算してくれます。

echo mb_strwidth("ABC", 'UTF-8');   // 3
echo mb_strwidth("太郎", 'UTF-8');  // 4(全角2文字 → 幅4)
PHP

これを使って、「見た目の幅」をそろえる右パディングも書けます。

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

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

    $padCount = $width - $currentWidth;

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

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


例題でイメージを固める

例題1:固定長ファイルの1項目を作る

仕様:

  • 名前は 10バイト
  • 足りない分はスペースで右パディング
  • UTF-8
$name = "太郎"; // UTF-8

$field = rightPadBytes($name, 10, ' ');

echo $field;
PHP

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

例題2:ログのカラムをざっくりそろえる(表示用)

$level  = "INFO";
$level2 = "警告";

echo '[' . rightPadDisplayWidth($level, 6)  . '] メッセージ1' . PHP_EOL;
echo '[' . rightPadDisplayWidth($level2, 6) . '] メッセージ2' . PHP_EOL;
PHP

rightPadDisplayWidth を使うと、
全角・半角が混ざっていても、見た目の幅をある程度そろえられます。


まとめ:今日からの「右パディング」の考え方

大事なポイントだけ整理します。

  • str_pad は「バイト数ベース」で長さを見ている
  • 外部仕様や固定長ファイルなど「バイト数」が決まっている場面では、そのまま使ってよい
  • 日本語を含むときは、まず mb_strcut で「バイト数で切るが文字は壊さない」→そのあと str_pad で埋める、という流れが安全
  • 画面の「見た目の幅」をそろえたいときは、mb_strwidth を使った別ユーティリティを用意する

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

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

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