LoginSignup
1
1

More than 3 years have passed since last update.

[PHP]文字列を固定長の他の文字列で埋める(マルチバイト対応)

Posted at

文字列を規定の桁数になるまで任意の文字で埋めるために、PHPのstr_pad()を使うことがあるかと思います。
ただし、以下のようなマルチバイト文字をstr_pad()にかけて指定した桁数の文字列を出力しようとしても、バイト数で計算されるため意図した通りに出力されません。

echo str_pad('東京', 8, '●', STR_PAD_RIGHT).PHP_EOL;
echo str_pad('名古屋', 8, '●', STR_PAD_LEFT).PHP_EOL;
echo str_pad('大阪', 8, '●', STR_PAD_BOTH);

出力結果は以下の通り…
8桁の文字列が出力されてほしいところですが、先に述べたように意図した通りになりません。
その上、文字化けになってしまいました。

東京�
名古屋
�大阪�

そこで、マルチバイト文字にも対応したmb_str_pad()を作成しました。
使い方はstr_pad()とほとんど変わりありませんが、バイト数ではなく文字数で計算するようになっています。

/**
 * 文字列を固定長の他の文字列で埋める(マルチバイト対応)
 *
 * @param string $input    対象の文字列
 * @param int    $pad_len  埋める文字数
 * @param string $pad_str  埋める文字列
 * @param int    $pad_type 埋め方(STR_PAD_RIGHT, STR_PAD_LEFT, STR_PAD_BOTH)
 * @param string $encoding 文字列のエンコーディング
 * @return string
 */
function mb_str_pad($input, $pad_len, $pad_str=' ', $pad_type=STR_PAD_RIGHT, $encoding=null)
{
    if (!$encoding || strtolower($encoding) == 'auto') {
        $encoding = mb_internal_encoding();
    }

    $input_len   = mb_strlen($input, $encoding);
    $pad_str_len = mb_strlen($pad_str, $encoding);
    $target_len  = $pad_len - $input_len;

    if (!$input_len || !$pad_str_len || $target_len <= 0) {
        return $input;
    }

    if ($pad_type === STR_PAD_BOTH) {
        $target_len /= 2;
    }

    $repeat = str_repeat($pad_str, ceil($target_len / $pad_str_len));

    if ($pad_type === STR_PAD_BOTH || $pad_type === STR_PAD_LEFT) {
        $left = mb_substr($repeat, 0, floor($target_len), $encoding);
    } else {
        $left = '';
    }

    if ($pad_type === STR_PAD_BOTH || $pad_type === STR_PAD_RIGHT) {
        $right = mb_substr($repeat, 0, ceil($target_len), $encoding);
    } else {
        $right = '';
    }

    return $left.$input.$right;
}

先ほどと同じ文字列を、mb_str_pad()にかけてみます。

echo mb_str_pad('東京', 8, '●', STR_PAD_RIGHT).PHP_EOL;
echo mb_str_pad('名古屋', 8, '●', STR_PAD_LEFT).PHP_EOL;
echo mb_str_pad('大阪', 8, '●', STR_PAD_BOTH);

出力結果は以下の通りです。

東京●●●●●●
●●●●●名古屋
●●●大阪●●●

今度は意図した通りの結果になりました!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1