Signature
vprintf(string $format, array $values): intPurpose
vprintf() writes a formatted string directly to the output. It works like printf(), except that the values to insert arrive in a single array instead of as separate arguments. That makes it a good fit when the values are already in an array, for example the result of explode(), a database-style row or a list built earlier in your script.
If you want the formatted text as a string instead of printing it, use vsprintf().
Signature
Parameters
$format: the template string. Ordinary characters are copied unchanged. Each conversion specification starts with%and follows the shape%[argnum$][flags][width][.precision]specifier.$values: an array of values. They are consumed in order by the specifications in the format. There is no default, so both parameters are required.
The main pieces of a specification are:
- argnum: a number followed by
$, such as%2$s, to pick a particular value by position (starting at 1). - flags:
-left-justifies,+forces a sign on positive numbers,0pads with zeros, and'xpads with the characterx. - width: the minimum number of characters in the result.
- precision: a period and a number. For
f,F,eandEit is the number of decimals. Forsit cuts the string off at that many characters. - specifier: the type of conversion, such as
d(signed integer),s(string),f(float),x(hexadecimal),b(binary),u(unsigned) or%(a literal percent sign that consumes no value).
Return value and failure cases
The function returns an int: the length of the string that was output, counted in bytes. Since PHP 8.0 it no longer returns false on failure. Instead it throws a ValueError when:
- the array holds fewer values than the format requires;
- a width or precision is negative or larger than
PHP_INT_MAX; - the format is invalid in a way that makes the argument count zero.
Example 1: zero-padded values and the return value
This splits a date and pads each part. The returned length includes the trailing newline.
$length = vprintf("%04d-%02d-%02d\n", explode('-', '1988-8-1'));
echo $length, "\n";1988-08-01 11
Example 2: alignment and positional arguments
A width with the - flag left-aligns text, while a width with a precision lines up decimals. In the second call, %2$s and %1$s select values by position, so the output order differs from the array order. Single quotes keep $s from being read as a variable.
$row = ['Widget', 4, 3.5];
vprintf("%-10s|%3d|%8.2f\n", $row);
vprintf('%2$s x %1$s' . "\n", ['apple', 3]);Widget | 4| 3.50 3 x apple
Example 3: too few values
When the array is shorter than the format needs, PHP 8 throws a ValueError. You can catch it like any other exception.
try {
vprintf('%s and %s', ['one']);
} catch (ValueError $e) {
echo get_class($e), "\n";
}ValueError
Edge cases
- Array keys are ignored. Only the order of the values matters, so an associative array is read from its first element onward. Use
%n$if you need a different order. - A literal percent sign must be written
%%. A lone%followed by something that is not a valid specification is treated as a conversion and can cause an error. - Bytes, not characters. Width, precision and the return value count bytes. With multibyte text such as UTF-8, padding and cutoffs with
%scan split or misalign characters. For such text, prepare padding with multibyte-aware functions instead. - The
cspecifier ignores width and padding. It prints one character for an integer code. - Type coercion. Values are converted to suit the specifier, so
%dapplied to'12abc'is treated as an integer conversion and does not preserve the text. - Floats and locale.
fis locale aware, whileFis not. UseFwhen you need a predictable decimal point. - Bare precision. A period with no number means a precision of 0. The manual notes that PHP 8.5.0 changes how a formatter without a precision is handled, so avoid relying on a bare period when you target several versions.
Common mistakes
- Passing separate arguments. Calling
vprintf($format, $a, $b)is wrong. The second parameter must be one array. - Expecting a string back. The function prints and returns a length. Use
vsprintf()when you need the text. - Printing the return value by accident.
echo vprintf(...)prints the formatted text and then the number. - Miscounting values. Each
%sor%dconsumes one value, except%%. Positional specifiers can reuse a value, but the array still has to be long enough for the highest position used. - Using double quotes with
%1$s. Inside double-quoted strings,$sis interpolated as a variable. Use single quotes or escape the dollar sign. - Padding multibyte strings. Byte-based widths give uneven columns for non-ASCII text.
Related functions
printf(): the same formatting with a variable argument list.sprintf()andvsprintf(): return the formatted string instead of printing it.fprintf()andvfprintf(): write to a stream.number_format(): formats numbers with thousands separators.sscanf(): parses text according to a format, roughly the reverse operation.
Recap
vprintf() prints a template filled with values from an array and returns the number of bytes written. Use flags, width and precision for alignment, %n$ for reordering, and expect a ValueError when the array is too short. When you need the string rather than output, choose vsprintf().
Tested examples
$length = vprintf("%04d-%02d-%02d\n", explode('-', '1988-8-1'));
echo $length, "\n";
1988-08-01 11
$row = ['Widget', 4, 3.5];
vprintf("%-10s|%3d|%8.2f\n", $row);
vprintf('%2$s x %1$s' . "\n", ['apple', 3]);
Widget | 4| 3.50 3 x apple
try {
vprintf('%s and %s', ['one']);
} catch (ValueError $e) {
echo get_class($e), "\n";
}
ValueError