1. ホーム
  2. PHP

【PHP】sprintf と number_format で数値・文字列を整形する方法

Share

PHP で数値や文字列を「見やすい形」に整えたい場面は数多くあります。たとえば「金額を 1,234 円のようにカンマ区切りで表示したい」「連番を 001、002 とゼロ埋めしたい」「小数を必ず 2 桁で揃えたい」といったケースです。こうした整形には、書式付きで文字列を組み立てる sprintf() / printf() と、数値を桁区切りして整える number_format() が役立ちます。この記事では、これらの関数の基本から変換指定子の意味、実践的な使い方、そしてつまずきやすいポイントまでを、初心者の方にも分かるように丁寧に解説します。

sprintf と number_format で何ができるか

sprintf() は「書式(フォーマット)」をひな型として渡し、その中の決められた記号(変換指定子)を実際の値に置き換えて、1 つの文字列を組み立てる関数です。「%d の部分に数値を入れる」「%s の部分に文字列を入れる」といった具合に、出力の形をきっちり指定できます。単純な文字列連結よりも、桁数やゼロ埋めなどの細かい整形ができるのが強みです。

一方の number_format() は、数値を「3 桁ごとのカンマ区切り」や「小数点以下の桁数固定」で整える専用の関数です。金額表示のように 1,234,567 という見た目を作りたいときに最適です。sprintf() でも桁数の調整はできますが、3 桁区切りのカンマは number_format() の得意分野です。役割を分けて覚えておくと使い分けに迷いません。

sprintf の基本の使い方

まずは最小の例を見てみましょう。第 1 引数に書式となる文字列を渡し、第 2 引数以降に「置き換えたい値」を順番に並べます。書式の中の %s(文字列)や %d(整数)が、後ろの引数で順に置き換えられます。

basic.php
<?php
// %s が "りんご"、%d が 150 に置き換わる
$text = sprintf("%s は %d 円です", "りんご", 150);

echo $text;
// りんご は 150 円です

変換指定子は必ず % で始まります。%s は値を文字列として、%d は整数として埋め込みます。指定子の数と、後ろに渡す引数の数・順番が対応している必要がある点に気をつけましょう。

printf は出力、sprintf は文字列を返す

sprintf() とよく似た関数に printf() があります。書式の書き方はまったく同じですが、結果の扱いが違います。printf() は整形した文字列をその場で出力します。対して sprintf() は整形した文字列を戻り値として返すだけで、出力はしません。変数に入れて後で使ったり、別の処理に渡したりしたいときは sprintf() を使います。

printf-vs-sprintf.php
<?php
// printf は整形してそのまま出力する
printf("合計: %d 円\n", 980);
// 合計: 980 円

// sprintf は出力せず、文字列を返す
$message = sprintf("合計: %d 円", 980);
echo $message; // 合計: 980 円

名前の先頭にある s は string(文字列)の頭文字で、「文字列を返す print」と覚えると区別しやすいです。HTML を組み立ててから echo したい WordPress のテンプレートなどでは、いったん sprintf() で文字列を作る書き方が多く使われます。

変換指定子と幅・精度の指定

sprintf() の本領は、% と変換文字のあいだに「フラグ」「幅」「精度」を書き足して、出力の見た目を細かく制御できる点にあります。よく使う変換指定子を整理しておきましょう。

指定子意味と例(引数の値 → 結果)
%s文字列として埋め込む。"PHP"PHP
%d整数(10 進数)として埋め込む。4242
%f浮動小数点数。既定では小数 6 桁。3.143.140000
%.2f小数点以下の桁数を指定(ここでは 2 桁)。3.141593.14
%05d5 桁になるよう先頭をゼロ埋め。4200042
%5d5 桁になるよう先頭を半角スペースで埋める。42␣␣␣42
%-5d- で左寄せ。右側をスペースで埋める。4242␣␣␣
%x / %X16 進数(小文字 / 大文字)。255ff / FF
%b2 進数。5101
%%パーセント記号そのものを出力。 → %

幅の指定は「最低でも何文字分の幅を取るか」を表します。値がその幅に満たない場合だけスペース(または 0)で埋められ、幅を超える値はそのまま全部表示されます。幅指定で値が切り捨てられることはありません。次のコードで動きを確認してみましょう。

specifiers.php
<?php
echo sprintf("[%05d]", 42);      // [00042]  ゼロ埋めで 5 桁
echo "\n";
echo sprintf("[%5d]", 42);       // [   42]  スペースで 5 桁ぶんの幅
echo "\n";
echo sprintf("[%-5d]", 42);      // [42   ]  左寄せ
echo "\n";
echo sprintf("[%.2f]", 3.14159); // [3.14]   小数 2 桁
echo "\n";
echo sprintf("[%8.2f]", 3.14159);// [    3.14] 全体 8 文字幅で小数 2 桁
echo "\n";
echo sprintf("%x / %X", 255, 255); // ff / FF  16 進数
echo "\n";
echo sprintf("達成率 100%%");      // 達成率 100%  %% で % を出力

%8.2f のように幅と精度を組み合わせると、「全体で 8 文字分の幅を取り、小数点以下は 2 桁」という指定になります。. の前が幅、後ろが精度(小数桁数)です。パーセント記号そのものを出したいときは %% と 2 つ続けて書く点も覚えておきましょう。% を 1 つだけ書くと、その後ろを変換指定子として解釈しようとしてしまいます。

number_format で数値を桁区切りする

金額のように 3 桁ごとにカンマを入れたいときは number_format() が最も簡単です。引数を 1 つだけ渡すと、整数に丸めたうえで 3 桁区切りのカンマを付けてくれます。

number-format-basic.php
<?php
// 第 2 引数を省略すると小数なし(整数)でカンマ区切り
echo number_format(1234567);
// 1,234,567

// 価格表示でよく使う形
$price = 1980;
echo number_format($price) . "円";
// 1,980円

number_format の引数

number_format() の構文は number_format(float $num, int $decimals = 0, string $decimal_separator = ".", string $thousands_separator = ","): string です。第 2 引数以降を指定すると、小数桁数や区切り文字を自由に変えられます。

引数説明
$num整形したい数値。
$decimals小数点以下の桁数。省略すると 0(整数に丸める)。
$decimal_separator小数点として使う文字。省略すると .(ピリオド)。
$thousands_separator3 桁ごとの区切り文字。省略すると ,(カンマ)。

小数桁数や区切り文字を変えたい場合は、第 2 引数以降を指定します。なお戻り値は数値ではなく文字列である点に注意してください(カンマが入るため数値型では表せません)。

number-format-args.php
<?php
// 小数 2 桁で固定し、カンマ区切り
echo number_format(1234.567, 2);
// 1,234.57

// 区切り文字を変える(小数点に「.」、3 桁区切りに半角スペース)
echo number_format(1234567.891, 0, ".", " ");
// 1 234 568

// ヨーロッパ式(小数点にカンマ、桁区切りにピリオド)
echo number_format(1234.5, 2, ",", ".");
// 1.234,50

実践的な整形の例

基本を押さえたところで、実際の開発でよく登場する整形パターンを見ていきましょう。

連番をゼロ埋めする

ファイル名や注文番号などで「001、002、003」のように桁を揃えたいときは、%03d のようにゼロ埋めの幅指定が便利です。0 がゼロ埋めの指示、3 が桁数を表します。

zero-padding.php
<?php
for ($i = 1; $i <= 3; $i++) {
    // 3 桁になるようゼロ埋めしてファイル名を作る
    echo sprintf("image_%03d.jpg\n", $i);
}
// image_001.jpg
// image_002.jpg
// image_003.jpg

金額をカンマ区切りで表示する

合計金額の表示では number_format()sprintf() を組み合わせると読みやすくなります。カンマ区切りは number_format() に任せ、その結果を %s で文字列として埋め込みます。

price.php
<?php
$total = 1234567;

// カンマ区切りは number_format、文字列の組み立ては sprintf に任せる
echo sprintf("ご請求金額: %s 円", number_format($total));
// ご請求金額: 1,234,567 円

小数点以下の桁を揃える

割合や評価点を「3.50」「4.00」のように常に小数 2 桁で表示したいときは、%.2fnumber_format($n, 2) を使います。どちらも値が割り切れても末尾の 0 を補ってくれるので、桁数が揃ってきれいに並びます。

decimals.php
<?php
$scores = [3.5, 4, 2.75];

foreach ($scores as $score) {
    // 常に小数 2 桁で表示する
    echo sprintf("評価: %.2f\n", $score);
}
// 評価: 3.50
// 評価: 4.00
// 評価: 2.75

引数の番号を指定して順序を入れ替える

%1$s のように % の直後に「番号 + $」を書くと、何番目の引数を使うかを明示できます。これを「位置指定(引数番号指定)」と呼びます。同じ値を 2 回使いたいときや、言語によって語順が変わる多言語対応で役立ちます。

positional.php
<?php
// %1$s は 1 番目の引数、%2$s は 2 番目の引数
echo sprintf('%1$s さん、%1$s さん、こちらは %2$s です', "山田", "佐藤");
// 山田 さん、山田 さん、こちらは 佐藤 です

このとき書式文字列はシングルクォートで囲むのが安全です。ダブルクォートで囲むと $s$1 の部分を PHP が変数とみなして展開しようとし、意図しない結果になることがあります。位置指定を使うときは特に注意してください。

整形した結果がずれる・想定と違うときの原因

「金額が四捨五入されて 1 円ずれた」「小数が消えた」といった結果は、関数の丸めや型変換の仕様を知らないことが原因のほとんどです。代表的なつまずきポイントを整理しておきましょう。

number_format は切り捨てではなく四捨五入する

number_format() で小数桁を減らすと、はみ出た桁は四捨五入されます。切り捨てだと思い込んでいると、合計金額が 1 円ずれて見えることがあります。これは %.2f による sprintf() の整形でも同様です。

rounding.php
<?php
echo number_format(2.345, 2); // 2.35 (切り上げ方向に四捨五入)
echo "\n";
echo number_format(1234.5);   // 1,235 (小数なしに丸める)
echo "\n";
echo sprintf("%.0f", 0.5);    // 1 (sprintf も四捨五入)

金額の計算で「必ず切り捨てたい」「必ず切り上げたい」という要件があるときは、表示の段階で number_format() に任せるのではなく、先に floor()(切り捨て)や ceil()(切り上げ)で値を丸めてから整形するようにしてください。表示用の整形と、金額計算そのものの丸めは分けて考えるのが安全です。

%d は小数を切り捨てる

四捨五入する number_format() とは対照的に、sprintf()%d は整数への変換なので、小数部分を単純に切り捨てます。3.99%d で出力しても 4 にはならず 3 になります。小数を四捨五入して整数にしたいなら、先に round() を通すか %.0f を使いましょう。

integer-cast.php
<?php
echo sprintf("%d", 3.99);  // 3  (小数は切り捨て)
echo "\n";
echo sprintf("%.0f", 3.99);// 4  (こちらは四捨五入)
echo "\n";
echo sprintf("%d", round(3.99)); // 4 (round で丸めてから)

文字列を %d に渡したときの挙動

フォームから受け取った値などは文字列になっています。これを %d に渡すと、PHP は文字列の先頭から数字として読める部分だけを整数に変換します。"12abc" なら 12、数字で始まらない "abc"0 になります。エラーにはならず静かに 0 になるため、バグに気づきにくいので注意が必要です。

string-to-number.php
<?php
echo sprintf("%d", "12abc"); // 12  先頭の数字だけ取り出す
echo "\n";
echo sprintf("%d", "abc");   // 0   数字で始まらないと 0
echo "\n";
// number_format は数値以外を渡すと TypeError になる(PHP 8 以降)
echo number_format((float) "1234.5"); // 1,234 明示的に数値へ変換する

外部から受け取った値を整形する前には、(int)(float) で明示的に数値へ変換したり、is_numeric() で数値として扱える文字列か確認したりしておくと、想定外の 0 や型エラーを防げます。

区切り文字とロケールの関係

number_format() はロケール設定の影響を受けず、引数で指定した区切り文字をそのまま使います。日本やアメリカでは「小数点はピリオド、桁区切りはカンマ」ですが、国によっては「小数点はカンマ、桁区切りはピリオド」という表記もあります。地域に合わせて表示を変えたいときは、第 3・第 4 引数で $decimal_separator$thousands_separator を明示的に指定してください。引数で指定するので挙動が環境に左右されず、結果が予測しやすいのが利点です。

まとめ

sprintf() は書式に変換指定子を並べて文字列を組み立てる関数で、%05d のゼロ埋め、%.2f の小数桁固定、%1$s の位置指定など、出力の見た目を細かく制御できます。printf() はその場で出力、sprintf() は文字列を返すという違いも押さえておきましょう。3 桁区切りのカンマは number_format() が得意で、小数桁数や区切り文字も引数で自由に指定できます。

使うときは、number_format()%.2f は四捨五入する一方で、%d は小数を切り捨てるという丸め方の違いに注意してください。また文字列を %d に渡すと先頭の数字だけが使われ、数字で始まらなければ 0 になります。表示用の整形と金額計算の丸めは分けて考え、外部からの値は事前に数値へ変換しておくと、ずれや型エラーを防げます。これらを押さえれば、数値や文字列の整形でつまずくことはほとんどなくなるはずです。

参考ページ