PHP 8.0: New *
precision and width modifiers in printf
printf
and its related functions (such as sprintf
) in PHP 8.0 support specifying the width/precision modifiers as a function parameter rather than hard-coding it to the format string itself.
%f
, the float formatter supports specifying the precision with%.3f
, where thefloat
is represented with a precision of3
. Similarly,%.5f
is for precision 5, etc.%s
, the string formatter supports specifying the length of the string.%.5
would limit the string to 5 bytes,%.10s
is for the first 10 bytes, etc.
In PHP 8, the width and precision modifiers can be set as a parameter to the printf
and other related functions. The width/precision modifier is indicated with *
, and should follow the same sequential order the printf
functions otherwise accept.
printf('%.*f', 3, 1.61803); // "1.618"
printf('%.3f', 1.61803); // "1.618"
In the snippet above, the first printf
call uses %.*f
format, and the precision is set as the second parameter. The result is identical to the second printf
call, where the precision is already specified in the format itself.
Positional parameters support the *
modifiers as well:
printf('%.*2$f', 1.61803, 3); // "1.618"
// ^^ ^
printf('%3$.*4$f', 42, 42, 1.61803, 3); // "1.618"
// ^^ ^
Precision must me an integer
Note that the precision must be an integer, and there is no type coercion even with strict typing is off. Attempting to set a precision with any value other than an integer will throw a ValueError
exception.
printf('%.*f', (string) 3, 1.618);
// Fatal error: Uncaught ValueError: Precision must be an integer in ...:...
Precision -1
is allowed in %g
/%G
and [%h
/%H
]
%g
/%G
and %h
/%H
specifiers allow -1
as the precision. For width and precision modifiers, only 0
and positive integers are allowed otherwise.
Backwards Compatibility Impact
Precision modifier and width modifiers are not understood in PHP versions prior to 8.0. They will not raise any warnings or exceptions.
Both width (%*
) and precision (%.*
) will be evaluated to empty strings.
PHP < 8.0 | PHP >= 8.0 | |
---|---|---|
printf('%.*f', 3, 1.61803) |
f |
1.618 |
printf('%.3f', 1.61803) |
1.618 |
1.618 |
printf('%*.*f', 7, 3, 1.61803) |
.*f |
1.618 |
printf('%7.3f', 1.61803) |
1.618 |
1.618 |
printf('%*d', 5, 17) |
d |
17 |
printf('%5d', 17) |
17 |
17 |
The *
modifiers are merely syntactic changes, and hardcoding the precision/width values in the format string itself ensures backwards compatibility with PHP versions prior to 8.0.