String formatting: sprintf, printf, number_format, money_format
Concept
PHP's string formatting functions serve different needs: sprintf builds formatted strings, printf outputs them directly, number_format handles locale-aware number display, and sscanf parses formatted strings.
sprintf($format, ...$values) is the workhorse. Format specifiers: %s string, %d integer, %f float, %e scientific, %x hex, %o octal, %b binary. Width and precision: %10s right-pads to 10, %-10s left-pads, %'.10s pads with ., %.2f two decimal places, %05d zero-pads to 5 digits. Argument swapping: %2$s %1$s reorders arguments — critical for internationalization where word order varies by language.
number_format($number, $decimals, $decPoint, $thousandsSep) formats numbers for display. The default locale uses . as decimal point and , as thousands separator. For European locales, swap them: number_format(1234567.89, 2, ',', '.') → "1.234.567,89". Note: number_format always returns a string; do not use the result in arithmetic.
money_format was deprecated in PHP 7.4 and removed in PHP 8.0. Use NumberFormatter from the intl extension for locale-aware currency formatting instead — it handles currency symbols, decimal places, and grouping rules correctly for any locale.
Code Example
<?php
declare(strict_types=1);
// Basic sprintf
$name = 'Codrut';
$age = 28;
echo sprintf("Name: %s, Age: %d\n", $name, $age);
// Width and alignment
$items = [['Widget', 9.99], ['Gadget', 149.00], ['Doohickey', 1.50]];
foreach ($items as [$item, $price]) {
echo sprintf("%-15s %8.2f EUR\n", $item, $price);
}
// "Widget 9.99 EUR"
// "Gadget 149.00 EUR"
// Zero-padding and hex
$id = 42;
echo sprintf('%08d', $id); // "00000042"
echo sprintf('0x%04X', 255); // "0x00FF"
// Argument swapping for i18n
$template_en = '%1$s has %2$d messages';
$template_fr = '%2$d messages pour %1$s';
echo sprintf($template_en, $name, 5); // "Codrut has 5 messages"
echo sprintf($template_fr, $name, 5); // "5 messages pour Codrut"
// number_format
$amount = 1234567.891;
echo number_format($amount, 2); // "1,234,567.89" (US)
echo number_format($amount, 2, ',', '.'); // "1.234.567,89" (EU)
echo number_format($amount, 0); // "1,234,568" (rounded)
// Modern currency formatting with intl extension
if (class_exists('NumberFormatter')) {
$fmt = new NumberFormatter('ro_RO', NumberFormatter::CURRENCY);
echo $fmt->formatCurrency(1234.56, 'RON'); // "1.234,56 RON"
$fmt_en = new NumberFormatter('en_US', NumberFormatter::CURRENCY);
echo $fmt_en->formatCurrency(1234.56, 'USD'); // "$1,234.56"
}
// sscanf — parse formatted input
[$day, $month, $year] = sscanf('15/01/2024', '%d/%d/%d');
echo "$year-$month-$day"; // "2024-1-15"