sprintf()は、書式と値のリストから組み立てた文字列を返します。書式の中の%のプレースホルダーが、それぞれ次の値に置き換えられます。sprintf('%s is %d years old', 'Ada', 36)は"Ada is 36 years old"を返します。printf()は同じ引数を受け取りますが、結果を返す代わりに出力します。
プレースホルダーは左から右へ順に埋められます。%.2fは常に小数点以下2桁を表示し(4.5ではなく4.50)、%05dは数値を5桁になるまでゼロで埋めます。
書式指定子
プレースホルダーは、%、任意の修飾子、型を表す1文字の順に書きます。
| 指定子 | 意味 | sprintf(...) | 結果 |
|---|---|---|---|
%s | 文字列 | sprintf('%s', 'PHP') | PHP |
%d | 整数(符号付き) | sprintf('%d', 42.9) | 42 |
%f | float、デフォルトで小数点以下6桁 | sprintf('%f', 1.5) | 1.500000 |
%.2f | float、小数点以下2桁 | sprintf('%.2f', 1.5) | 1.50 |
%e | 指数表記 | sprintf('%e', 1234.5678) | 1.234568e+3 |
%x / %X | 16進数 | sprintf('%x', 255) | ff |
%o | 8進数 | sprintf('%o', 8) | 10 |
%b | 2進数 | sprintf('%b', 5) | 101 |
%c | 文字コードから文字 | sprintf('%c', 65) | A |
%u | 符号なし整数 | sprintf('%u', 3) | 3 |
%% | パーセント記号そのもの | sprintf('%d%%', 50) | 50% |
下の値を変えて、もう一度実行してみてください。
%dはfloatを0の方向に切り捨てるので、42.9は42になります。43にしたいなら、先に丸めます:sprintf('%d', round(42.9))。'abc'のような数値でない文字列は、%dでは0になります。
ゼロ埋めする
%と型の文字の間には、埋める文字と幅を書けます。%05dは「幅5まで0で埋める」という意味です。注文番号、請求書のID、時刻、日付を整形する定番の方法です。
幅は最小値です。幅より長い数値はそのまま全部出力されます。
%05.2f:幅と小数点以下の桁数を一緒に指定する
floatでは、幅は小数点やマイナス記号も含め、結果のすべての文字を数えます。そのため3.14159に%05.2fを使うと03.14になります。全体で5文字、そのうち2文字が小数点以下です。
%fは現在のロケール(setlocale()で設定)の小数点を使いますが、%Fは常にドットを使います。コードでロケールを設定していて、JSON、CSV、APIのためにドットが必要なら%Fを使いましょう。
テキストを列に揃える
正の幅は右揃え、幅の前の-は左揃え、'のあとに文字を書くと埋める文字を指定できます。組み合わせれば、プレーンテキストのレポートやレシートの列を揃えられます。
%-14sは商品名を右側で14文字まで埋め、%8.2fは価格を8文字の中で右揃えにし、空文字列に対する%'-27sは27個のダッシュの線を出力します。%'*10sは空白の代わりに*で埋めます。
引数に番号を付けて再利用や並べ替えをする
%1$sは「1つ目の引数を文字列として」、%2$dは「2つ目を整数として」の意味です。番号付きのプレースホルダーを使えば、引数のリストを変えずに値を2回使ったり順番を変えたりでき、言語によって語順が違う場合に翻訳者が必要とする機能です。
vsprintf、printfと戻り値
vsprintf()は値を1つの配列で受け取るので、値がすでに配列に入っているときに便利です。printf()は出力したバイト数を返し、vprintf()はprintf()の配列版です。
printf()の数には改行も含まれるので、"Hello\n"は6バイトです。マルチバイトのテキストでは、文字ではなくバイトを数えます。
引数が足りないとエラーが投げられる
PHP 8以降、値よりプレースホルダーが多い書式は、falseを返す代わりにArgumentCountErrorを投げます。このエラーが出たら、%のプレースホルダー(%%は除く)を数えてください。
メッセージは書式の文字列も引数として数えます:ArgumentCountError: 4 arguments are required, 3 given。余分な引数は黙って無視されるので、逆のミスはエラーとして表れません。sprintfの結果がおかしく見えたら、書式と値を並べて出力してみましょう。桁区切りのカンマだけが必要なら、sprintfで作るよりnumber_format()のほうが簡単です。修飾子の完全な一覧はphp.netにあります。
よくある質問
PHPで数値をゼロ埋めするには?
sprintf('%05d', 42)を使うと"00042"が返ります。0が埋める文字で、5が全体の幅です。文字列ならstr_pad('42', 5, '0', STR_PAD_LEFT)で同じ結果になります。
sprintfで数値を小数点以下2桁に整形するには?
%.2fを使います:sprintf('%.2f', 3.14159)は"3.14"を、sprintf('%.2f', 5)は"5.00"を返します。幅も加えれば埋めることもできます:%08.2fは"00003.14"になります。
PHPのprintfとsprintfの違いは何ですか?
sprintf()は整形した文字列を返すので、変数に保存できます。printf()はすぐに出力し、出力したバイト数を返します。echo sprintf(...)とprintf(...)の出力は同じです。
PHPの%sはどういう意味ですか?
%sはsprintf()とprintf()で文字列を入れるプレースホルダーです:sprintf('Hello, %s', 'Ada')は"Hello, Ada"を返します。%sに渡した数値は文字列に変換されます。%dは整数用、%fはfloat用です。
sprintfで同じ引数を2回使うには?
プレースホルダーに番号を付けます:sprintf('%1$s loves %2$s, and %2$s loves %1$s', 'Ada', 'PHP')。書式はシングルクォートで囲みます。ダブルクォートの中ではPHPが$sを変数として読むので、"%1$s"は%1のあとに$sの値が続いたものになります。