0

String formatting: sprintf, printf, number_format, money_format

Beginner5 min read·php-03-008

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
<?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"