PHP Conference China 2020

vprintf

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

vprintfフォーマットされた文字列を出力する

説明

vprintf ( string $format , array $args ) : int

formatに基づき文字列フォーマットされた文字列を出力します (フォーマットは sprintf() のドキュメントに既述されています)。

printf() と動作は同じですが、可変長の引数ではなく、 配列を引数として受け取ります。

パラメータ

format

0個以上のディレクティブで構成されるフォーマット文字列: 変換結果に直接コピーされる通常文字列 (% は除きます) と、変換仕様。 これらのいずれも、自分が持つパラメータを取得します。

変換の仕様は、以下のプロトタイプに従います: %[argnum$][flags][width][.precision]specifier.

Argnum

何個の引数を変換の対象にするかを指定するために、 数値の後にドル記号 $ を続けます。

フラグ一覧
フラグ 説明
- 与えられたフィールドの幅を左寄せにします。 右寄せがデフォルトです。
+ 正の数値の前に付ける + 符号です; デフォルトは、負の数にだけマイナスの符号が数値の前に付きます。
(space) スペースに変換される詰め物です。 これがデフォルトです。
0 数値の左側を0埋めします。 s 指定子を使うと、 右側にも0埋めできます。
'(char) 指定された (char) で埋めます。

Width

(最小で)何文字がこの変換結果に含まれるかを数値で指定します。

Precision

ピリオド . の後に数値を続けますが、 その意味は指定子に依存します:

  • e, E, fF 指定子の場合: 小数点の後に表示する桁数 (デフォルトでは、この値は6です)
  • gG 指定子の場合: 表示する最大の有効桁数
  • s 指定子の場合: 文字列を切り捨てる時点、つまり、文字列の最大の長さを設定します。

注意: 明示的に精度を指定せず、ピリオドを指定した場合、精度は0として扱われます。

注意: 位置を示す指定子に、PHP_INT_MAX を超える値を指定すると、警告が発生します。

指定子の一覧
指定子 説明
% 文字通り、パーセント文字です。 引数は不要です。
b 引数は数値として扱われ、バイナリ値として表現されます。
c 引数は数値として扱われ、ASCII文字として表現されます。
d 引数は数値として扱われ、(符号付き)小数値として表現されます。
e 引数は科学的記法で表現された値(e.g. 1.2e+2)として扱われます。 PHP 5.2.1 以降では、precision 指定子が小数点以降の桁数を表します。 それより前のバージョンでは、(ひと桁少ない) 有効桁数として解釈されていました。
E e 指定子に似ていますが、 大文字を使います(e.g. 1.2E+2)
f 引数は小数として扱われ、浮動小数値として表現されます(ロケールを考慮します)。
F 引数は小数として扱われ、浮動小数値として表現されます(ロケールを考慮しません)。 PHP 5.0.3 以降で利用可能です
g

汎用フォーマット

P を精度を表す、ゼロでない値とします。 精度が省略された場合、Pの値は6です。 精度に0を指定した場合、Pの値は1になります。 この場合、 E 指定子の変換結果は、 X乗になります。

P > X ≥ −4 の場合、E 指定子の変換結果となり、精度は、P − (X + 1) になります。 そうでない場合、e 指定子の変換結果となり、 精度は、P - 1 になります。

G g 指定子に似ていますが、 Ef を使います。
o 引数は数値として扱われ、8進数値として表現されます。
s 引数は文字列として扱われ、文字列として表現されます。
u 引数は数値として扱われ、符号なし小数値として表現されます。
x 引数は数値として扱われ、16進数値(小文字)として表現されます。
X 引数は数値として扱われ、16進数値(大文字)として表現されます。

警告

c 指定子はパディングと幅を無視します

警告

文字列と width 指定子を、1文字の表現に1バイト以上必要な文字セットと一緒に使おうとすると、 期待しない結果になるかもしれません。

値は、指定子の型に合うように強制されます:

型のハンドリング
指定子
string s
integer d, u, c, o, x, X, b
double g, G, e, E, f, F

args

返り値

出力された文字列の長さを返します。

例1 vprintf(): 整数のゼロ埋め

<?php
vprintf
("%04d-%02d-%02d"explode('-''1988-8-1'));
?>

上の例の出力は以下となります。

1988-08-01

参考

  • printf() - フォーマット済みの文字列を出力する
  • sprintf() - フォーマットされた文字列を返す
  • fprintf() - フォーマットされた文字列をストリームに書き込む
  • vsprintf() - フォーマットされた文字列を返す
  • vfprintf() - フォーマットされた文字列をストリームに書き込む
  • sscanf() - フォーマット文字列に基づき入力を処理する
  • fscanf() - フォーマットに基づきファイルからの入力を処理する
  • number_format() - 数字を千位毎にグループ化してフォーマットする
  • date() - ローカルの日付/時刻を書式化する

add a note add a note

User Contributed Notes 8 notes

up
9
steve at stevelockwood dot net
5 years ago
If, instead of an array, you pass an object PHP will automatically cast the object as an array so you can use it directly in vprintf.
<?php
$object
= new stdClass();
$object->Property1 = 'Value 1';
$object->Property2 = 'Value 2';
vprintf('%-20s %-20s', $object);

/* will output
Value 1              Value 2            
*/
?>
up
1
tehjosh at gamingg dot net
13 years ago
To toolofthesystem at gmail dot com:

You don't need to use output buffering with vprintf() because you can use vsprintf(), which has the same functionality as vprintf(), except that it returns the resulting string instead of outputting it.
up
0
taken from &#34;Php Phrasebook&#34;
12 years ago
<?php
$string
= 'The site runs on PHP '.phpversion();
preg_match('/php ((\d)\.\d\.\d+)/i',$string,$matches);
print_r($matches);
vprintf('Match: %s<br /> Version %s; Major:%d.',$matches);
?>

output:
Array ( [0] => PHP 5.2.5 [1] => 5.2.5 [2] => 5 )
Match: PHP 5.2.5 Version 5.2.5; Major:5.

For preg_match:

If matches  is provided, then it is filled with the results of search. $matches[0] will contain the text that matched the full pattern, $matches[1]  will have the text that matched the first captured parenthesized subpattern, and so on.
up
0
toolofthesystem at gmail dot com
13 years ago
This function comes useful sometimes when trying to list information returned from MySQL:

function print_sql($query,$printf){
    $sql_sql = mysql_query($query);
    while($sql = mysql_fetch_row($sql_sql)){
        vprintf($printf,$sql);
    }
}

Unfortunately, this seems to sneak its way past output buffering when I tried creating an argument to allow it to be contained in a returned string... either that or I didn't do it right.
up
0
caleb at tekhawk dot com
13 years ago
i know that you can use %1$s or %3$s to select the first or third string but how can you or can you use array names to select it

something like %'user'$s $'email'$s

i tend to add things to my databases over time and this could save loads of recoding
up
-1
phpcoder at gmail dot com
1 year ago
Using the ... operator, vprintf($format, $array) is basically just printf($format, ...$array).
up
-2
Chris
7 years ago
Another way to display arrays is use an array_walk(). This can be useful inline echo/print where a foreach wouldn't work, e.g.

<?php
echo "These errors: ", (unset)array_walk($msgs, function($a) { echo "<p>$a</p>"; } ), "must be corrected.";
?>
up
-2
badcop666 at hotmail dot com
12 years ago
For blocks of text, sprintf() is slow according to my tests.

Also, having the mapping between place-holders and the list of actual variables or datastructures often makes this code difficult to read. But the printf() family are widely supported and have a huge range of nice features. Performance is a cold mistress though!

From an ease-of-reading and maintenance, debugging point of view, I much prefer HEREDOC and "...{$variable}..." methods.

For a block of HTML markup with place holders, the fastest by far was:-

?>
<div> markup etc<?= $variable ?>more markup
<?

My tests comprised 20 runs of a loop of 1 million iterations with output buffering, ditching the buffer on each loop.

The timings ranged from average 2.1msec/million repetitions for the <?= $var ?> method up to 7.6msec/million using printf().

I'll try some benchmarking tools too, since I just wrote this myself and it could be introducing bias, but they've run on dev servers with low load.

Hopefully interesting.
To Top