Human readable number formatting in PHP

Amit Merchant · February 10, 2022 ·

Numbers are tricky. Numbers are tricky because they have been used as a metric for a lot of things. Currency, scale, weather, science to name a few. And since numbers are associated with several different things, it’s important to represent them in a way humans can understand.

For instance, if a number is associated with a currency, it can be coupled with the respective currency symbol (e.g. 20 USD or $20). Or as the numbers get larger, we break them into thousand, million, billion, and so on.

Fortunately for us, it’s quite easy to work with these scenarios in PHP using a relatively lesser popular NumberFormatter class. And that’s what I’m going to cover in this article.

The NumberFormatter class

The NumberFormatter class has been shipped since PHP 5 and onwards. The class consists of numerous methods using which you can format numbers, currencies, and percentages according to the specified or default locale.

Here’s how the class would look like.

class NumberFormatter {
    /* Methods */
    public __construct(string $locale, int $style, ?string $pattern = null)
    public static create(string $locale, int $style, ?string $pattern = null): ?NumberFormatter
    public formatCurrency(float $amount, string $currency): string|false
    public format(int|float $num, int $type = NumberFormatter::TYPE_DEFAULT): string|false
    public getAttribute(int $attribute): int|float|false
    public getErrorCode(): int
    public getErrorMessage(): string
    public getLocale(int $type = ULOC_ACTUAL_LOCALE): string|false
    public getPattern(): string|false
    public getSymbol(int $symbol): string|false
    public getTextAttribute(int $attribute): string|false
    public parseCurrency(string $string, string &$currency, int &$offset = null): float|false
    public parse(string $string, int $type = NumberFormatter::TYPE_DOUBLE, int &$offset = null): int|float|false
    public setAttribute(int $attribute, int|float $value): bool
    public setPattern(string $pattern): bool
    public setSymbol(int $symbol, string $value): bool
    public setTextAttribute(int $attribute, string $value): bool
}

Since NumberFormatter is locale-sensitive, you need to create a new NumberFormatter for each locale.

Important: One thing to note here is, to use this class, you must install the intl extension on your machine. Otherwise, PHP won’t be able to find this class when you try to utilize it.

Now, we will see all the things you can do using this class.

Human-readable number representation

Like I mentioned earlier, we humans tend to express bigger numbers in form of thousands (K), millions (M), billions (B), and so on.

So, for instance, if we want to represent 10000 as 10K, here’s how we can do it using the NumberFormatter class.

$human_readable = new \NumberFormatter(
    'en_US', 
    \NumberFormatter::PADDING_POSITION
);

echo $human_readable->format(10000); // 10K
echo $human_readable->format(1000000); // 1M
echo $human_readable->format(1000000000); // 1B

Here, the first argument is the locale (en_US in our case) and the second argument is the style in which we want to represent the number.

Spell-out Numbers

It’s also possible to spell out any number just by changing the style like so.

$spell_out = new \NumberFormatter(
    'en_US', 
    \NumberFormatter::SPELLOUT
);

echo $spell_out->format(11300);
// Outputs: eleven thousand three hundred

Currency formatting

We can use this class to print numbers that consist of a certain currency. Here’s how 100 can be represented as US Dollars.

$currency = new \NumberFormatter(
    'en_IT', 
    \NumberFormatter::CURRENCY
);

echo $currency->format(100); // $100.00

Or if we use a European locale…

$currency = new \NumberFormatter(
    'en_IT', 
    \NumberFormatter::CURRENCY
);

echo $currency->format(100); // €100.00

You can format from one currency (Euro) to another currency (USD) like so.

$currency = new \NumberFormatter(
    'en_IT', 
    \NumberFormatter::CURRENCY
);

echo $currency->formatCurrency(100, "USD");
// $100.00

Scientific format

Numbers can even be formatted in the scientific format.

$scintific_format = new \NumberFormatter(
    'en_US', 
    \NumberFormatter::SCIENTIFIC
);

echo $scintific_format->format(1000);
// 1E7

Time representation

A number can be represented as a time duration counterpart of it.

$time_format = new \NumberFormatter(
    'en_US', 
    \NumberFormatter::DURATION
);

echo $time_format->format(1000);
// 16:40

As you can see, it prints “16:40” which means “16 hours, 40 minutes”.

Conclusion

There are a lot of other styles that you can use with this class apart from what I have mention in this article. So, play around with it and you might end up with something you might be looking for.

Though the NumberFormatter class is not new, it’s sort of underutilized in my opinion. Maybe because the documentation of it is not that great with very few or non-existent examples.

But if used well, it can easily satisfy your number-formatting needs in PHP!

Learn the fundamentals of PHP 8 (and 8.1), the latest version of PHP, and how to use it today with my new book PHP 8 in a Nutshell. It's a no-fluff and easy-to-read guide to the latest features and nitty-gritty details of PHP 8. So, if you're looking for a quick and easy way to PHP 8, this is the book for you.

👋 Hi there! I'm Amit. I write articles about all things web development. If you like what I write and want me to continue doing the same, I would like you buy me some coffees. I'd highly appreciate that. Cheers!

Comments?