Signature
sprintf(string $format, mixed ...$values): stringPurpose
sprintf() builds a string from a template and a list of values. It does not print anything; it returns the result, so you can store it, compare it, pass it to another function, or echo it yourself. Typical uses are zero-padded identifiers, aligned text columns, fixed-decimal prices and message templates that need their values in a different order.
Signature
Parameters
$format is the template. Ordinary characters are copied unchanged. Each conversion specification starts with % and follows this shape: %[argnum$][flags][width][.precision]specifier.
- argnum: an integer followed by
$, such as%2$s. It selects which argument to use, so values can be reordered or reused. It must come immediately after the%. - flags:
-left-justifies,+shows a sign on positive numbers,0pads with zeros, a space pads with spaces (the default), and'xpads with the characterx. - width: the minimum length of the converted value. A
*takes the width from an extra integer argument. - precision: a
.followed by a number. Fore,E,fandFit is the number of digits after the decimal point (default 6). Forsit is the maximum number of characters. Forg,G,handHit is the maximum number of significant digits. - specifier: the conversion. Common ones are
d(signed integer),u(unsigned),s(string),f/F(float),e/E(scientific),x/X(hex),o(octal),b(binary),c(character from a code) and%(a literal percent sign, which consumes no argument).
...$values holds the values to insert, consumed in order unless argnum says otherwise. Values are coerced to the type the specifier needs.
Return value and failures
The function returns the formatted string. Since PHP 8.0 it no longer returns false on failure. Instead it throws:
ArgumentCountErrorwhen fewer arguments are supplied than the format requires;ValueErrorwhen no arguments are given, or when a width or precision is negative or larger thanPHP_INT_MAX.
Example 1: padding, signs and number bases
echo sprintf("%04d-%02d-%02d", 2005, 5, 6), PHP_EOL;
echo sprintf("%'.9d", 123), PHP_EOL;
echo sprintf("%+d %+d", 5, -5), PHP_EOL;
echo sprintf("%5.1f%% %X %b", 45.67, 255, 5), PHP_EOL;2005-05-06 ......123 +5 -5 45.7% FF 101
The first line builds an ISO-style date from integers. The second pads with dots using the ' flag. The third forces a + on positive numbers. The last one rounds to one decimal, prints a literal %, then shows hexadecimal and binary.
Example 2: an aligned text table
$rows = [['Pen', 1.5, 3], ['Notebook', 12.249, 2]];
foreach ($rows as [$name, $price, $qty]) {
echo sprintf("%-10s|%8.2f|%3d", $name, $price, $qty), PHP_EOL;
}Pen | 1.50| 3 Notebook | 12.25| 2
The - flag left-aligns the name in a ten-character field, while the numbers stay right-aligned by default. %8.2f reserves eight characters and rounds to two decimals.
Example 3: argument numbering and errors
echo sprintf('The %2$s contains %1$04d monkeys.', 5, 'tree'), PHP_EOL;
try {
echo sprintf('%d and %d', 1), PHP_EOL;
} catch (ArgumentCountError $e) {
echo get_class($e), PHP_EOL;
}The tree contains 0005 monkeys. ArgumentCountError
With %2$s and %1$04d, the template decides the order, which helps when translated sentences place values differently. The second call asks for two values but receives one, so PHP throws ArgumentCountError.
Edge cases
- Rounding is for display.
%.2fformats a float but the stored value is unchanged. Floats such as 12.249 are binary approximations, so values that sit exactly on a rounding boundary can surprise you. - Locale.
%fis locale aware, while%Fis not. Use%Fwhen the output must always use a dot as the decimal separator. - Width counts bytes. With multibyte text,
%s, width and precision work on bytes, so padding or truncation can split or misalign UTF-8 characters. %cignores padding. It outputs a single character from an integer code regardless of width.- Precision on strings truncates.
%.3skeeps at most three characters (bytes). - Bare period. The manual records a change in PHP 8.5.0 for a precision written as just a period. To stay portable, always write an explicit number such as
%.0f.
Common mistakes
- Forgetting to echo.
sprintf()returns the string;printf()is the function that outputs it. - Mismatched order. Passing values in a different order than the placeholders swaps them silently, because
%dand%swill happily coerce almost anything. Useargnum$when order may vary. - Unescaped percent signs. A literal percent must be written
%%. A lone%followed by text is parsed as a conversion. - Putting
argnum$after flags.%04$dis wrong; write%1$04d. - Mixing user-controlled formats with data. Never let untrusted input become the format string, since it controls how many arguments are required.
- Using it for thousands separators.
sprintf()has no grouping option; usenumber_format()for that.
Related functions
printf() outputs a formatted string, vsprintf() takes the values as an array, fprintf() writes to a stream, number_format() groups thousands, sscanf() parses text using a similar format, and date() formats timestamps.
Recap
Use sprintf() when you want a returned, precisely formatted string. Learn the order %[argnum$][flags][width][.precision]specifier, prefer %F for locale-independent floats, escape literal percents as %%, and expect ArgumentCountError when arguments are missing.
Tested examples
echo sprintf("%04d-%02d-%02d", 2005, 5, 6), PHP_EOL;
echo sprintf("%'.9d", 123), PHP_EOL;
echo sprintf("%+d %+d", 5, -5), PHP_EOL;
echo sprintf("%5.1f%% %X %b", 45.67, 255, 5), PHP_EOL;
2005-05-06 ......123 +5 -5 45.7% FF 101
$rows = [['Pen', 1.5, 3], ['Notebook', 12.249, 2]];
foreach ($rows as [$name, $price, $qty]) {
echo sprintf("%-10s|%8.2f|%3d", $name, $price, $qty), PHP_EOL;
}
Pen | 1.50| 3 Notebook | 12.25| 2
echo sprintf('The %2$s contains %1$04d monkeys.', 5, 'tree'), PHP_EOL;
try {
echo sprintf('%d and %d', 1), PHP_EOL;
} catch (ArgumentCountError $e) {
echo get_class($e), PHP_EOL;
}
The tree contains 0005 monkeys. ArgumentCountError