Formatting: sprintf and number_format
In the first lesson of this theme, double quotes were a form with blanks. Real forms often have rules for their blanks: "amount, two digits after the decimal point", "order number, three digits". PHP sets such rules for numbers with formatting functions.
A price shows why you need them. Let's divide 10 by 3:
<?php
$price = 10 / 3;
echo $price, "\n"; // 3.3333333333333
echo sprintf('%.2f', $price), "\n"; // 3.33
printf("%s: %d pcs, %.2f each\n", 'pen', 3, $price);
// pen: 3 pcs, 3.33 eachecho prints a fractional number with up to 14 significant digits: one three before the point and thirteen after it. That is far too many for a price, and sprintf keeps two digits after the point.
sprintf: a template with blanks
sprintf takes a template and the values for it, and returns the finished string. Every % sign in the template starts a blank, a format specifier. The letter at its end says what kind of value goes there.
%s: a string
It fills the value in as text. In the example %s received 'pen'.
%d: an integer
It fills in the number without its fractional part. The fraction is dropped, not rounded: sprintf('%d', 9.99) gives 9.
%.2f: a fractional number
It fills in the number with two digits after the point and rounds it: 3.333… becomes 3.33. The digit after the point sets how many digits to keep.
Width and zeros
Before the point you can give a width, the number of characters the whole number takes, point included:
echo sprintf('%05.2f', 3.14159), "\n"; // 03.14Let's take %05.2f apart:
0means fill the empty places with zeros, not spaces.5means the number takes at least five characters..2means two digits after the point.fmeans a fractional number.
The number 3.14 takes four characters, so sprintf adds one zero on the left.
The values are filled in by order: the first into the first blank, the second into the second. printf works the same way, but instead of returning the string it prints it right away.
This is where the form stops being an exact picture. A real form holds exactly what you wrote in it, while sprintf changes the value to fit the blank: %d cuts off the fraction, %.2f rounds.
number_format and str_pad
Two functions prepare a number for a human reader.
number_format
number_format adds digit grouping and decimal places. Its arguments, in order:
- the number;
- how many digits after the decimal point;
- what separates the fraction;
- what separates the groups.
If you pass only the number, it rounds to a whole number and puts commas between the groups, as English text does.
str_pad
str_pad pads a string to the length you need: order number 7 becomes 007. Without STR_PAD_LEFT the characters are added on the right.
echo number_format(1234567.891), "\n"; // 1,234,568
echo number_format(1234567.891, 2, ',', ' '), "\n"; // 1 234 567,89
echo str_pad('7', 3, '0', STR_PAD_LEFT), "\n"; // 007
echo str_pad('ab', 5, '.'), "|\n"; // ab...|The second line is the notation a Russian reader expects: a space between digit groups and a comma before the kopecks.
Common mistake
A number was formatted, and then the program went on calculating with it:
$sum = number_format(1234.5, 2);
echo $sum + 1, "\n"; // ✗Warning: A non-numeric value encounterednumber_format returned the string '1,234.50'. To PHP, a comma is not part of a number: it takes only the 1 at the start of the string, issues a warning and prints 2. Calculate with numbers, and format at the very end, right before output: number_format(1234.5 + 1, 2) gives 1,235.50.
Key points
echoprints a fractional number with up to 14 significant digits, so prices and totals are formatted before output.sprintffills values into a template:%sa string,%dan integer,%.2ftwo digits after the point;printfprints the result right away.number_formatadds digit grouping and decimal places, andstr_padpads a string to the length you need.- The result of formatting is a string: calculate with numbers, format before output.