Strings7 min readExamples run on PHP 8.5.10

vprintf()

Learn how PHP 8.4 vprintf() prints a formatted string from an array of values, what it returns, and which errors and mistakes to watch for.

Signature

vprintf(string $format, array $values): int
Available since PHP 4.1.07.48.08.18.28.38.48.5All versions →

Purpose

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, 0 pads with zeros, and 'x pads with the character x.
  • width: the minimum number of characters in the result.
  • precision: a period and a number. For f, F, e and E it is the number of decimals. For s it 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.

Example
<?php
$length = vprintf("%04d-%02d-%02d\n", explode('-', '1988-8-1'));
echo $length, "\n";
Output
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.

Example
<?php
$row = ['Widget', 4, 3.5];
vprintf("%-10s|%3d|%8.2f\n", $row);
vprintf('%2$s x %1$s' . "\n", ['apple', 3]);
Output
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.

Example
<?php
try {
    vprintf('%s and %s', ['one']);
} catch (ValueError $e) {
    echo get_class($e), "\n";
}
Output
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 %s can split or misalign characters. For such text, prepare padding with multibyte-aware functions instead.
  • The c specifier ignores width and padding. It prints one character for an integer code.
  • Type coercion. Values are converted to suit the specifier, so %d applied to '12abc' is treated as an integer conversion and does not preserve the text.
  • Floats and locale. f is locale aware, while F is not. Use F when 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

  1. Passing separate arguments. Calling vprintf($format, $a, $b) is wrong. The second parameter must be one array.
  2. Expecting a string back. The function prints and returns a length. Use vsprintf() when you need the text.
  3. Printing the return value by accident. echo vprintf(...) prints the formatted text and then the number.
  4. Miscounting values. Each %s or %d consumes one value, except %%. Positional specifiers can reuse a value, but the array still has to be long enough for the highest position used.
  5. Using double quotes with %1$s. Inside double-quoted strings, $s is interpolated as a variable. Use single quotes or escape the dollar sign.
  6. Padding multibyte strings. Byte-based widths give uneven columns for non-ASCII text.
  • printf(): the same formatting with a variable argument list.
  • sprintf() and vsprintf(): return the formatted string instead of printing it.
  • fprintf() and vfprintf(): 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

Zero-padded date parts and the returned length
<?php
$length = vprintf("%04d-%02d-%02d\n", explode('-', '1988-8-1'));
echo $length, "\n";
Output
1988-08-01
11
Column alignment and positional arguments
<?php
$row = ['Widget', 4, 3.5];
vprintf("%-10s|%3d|%8.2f\n", $row);
vprintf('%2$s x %1$s' . "\n", ['apple', 3]);
Output
Widget    |  4|    3.50
3 x apple
ValueError when the array is too short
<?php
try {
    vprintf('%s and %s', ['one']);
} catch (ValueError $e) {
    echo get_class($e), "\n";
}
Output
ValueError