Number::spellOrdinal

Spells a number's ordinal form as words, turning 3 into third and 21 into twenty-first.

Signature
Number::spellOrdinal(int|float $number, ?string $locale = null): string
  • Added in Laravel 11.34.0

Parameters

ParameterTypeDescription
$$numberint|floatThe value to spell as an ordinal.
$$localeoptional?string= nullICU locale supplying the spell-out ruleset. Falls back to the Number class locale.

Return value

stringThe ordinal written out in words, for example 'twenty-first'.

Errors

Throws RuntimeException when the intl PHP extension is not loaded.

Changelog

  • PHP 11.34.0Added to the Number class.

Number::spellOrdinal() is the word form of Number::ordinal: 1 becomes first, 2 becomes second, 21 becomes twenty-first. Internally it creates a spell-out formatter and switches its default ruleset to %spellout-ordinal.

The ruleset is not universal

That ruleset name is the catch. Not every ICU locale defines %spellout-ordinal, and several that do define gendered variants such as %spellout-ordinal-masculine instead. When the ruleset is missing, NumberFormatter does not throw — it falls back, and you may get the cardinal spelling or an empty result depending on the ICU version bundled with your PHP. Test the specific locales you support rather than assuming parity with English.

No thresholds here

Unlike Number::spell, there are no after and until parameters. If your style guide says "first through ninth in words, 10th onward in digits", you have to branch yourself and call Number::ordinal() for the rest.

Fractions make no sense as ordinals; pass integers. And like every locale-aware method on this class, it needs the intl extension.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Writing 'your third failed login attempt' in a security email
  • Producing 'the twenty-first of the month' in a contract clause
  • Labelling tournament placings in prose rather than as 1st, 2nd, 3rd

Frequently asked questions

What is the difference between ordinal and spellOrdinal?

ordinal() keeps the numeral and appends an indicator ('21st'); spellOrdinal() writes the whole thing as words ('twenty-first'). Use the first in tables and the second in running prose.

Which Laravel version added Number::spellOrdinal?

Laravel 11.34.0. On earlier versions you have to build a NumberFormatter yourself and set the DEFAULT_RULESET text attribute to %spellout-ordinal.

Can I spell ordinals only below a threshold like Number::spell does?

Not through this method — it takes no after or until parameters. Branch on the value yourself and fall back to Number::ordinal() above your cut-off.

More examples

Words below ten, digits above

Prints first, third, ninth, then 10th and 25th. spellOrdinal() has no after or until parameters, so the threshold has to be a plain comparison in your own code — this is the shape that mirrors what Number::spell(until: 10) does for cardinals.

Example · php
<?php

use Illuminate\Support\Number;

function placing(int $n): string
{
    return $n < 10 ? Number::spellOrdinal($n) : Number::ordinal($n);
}

foreach ([1, 3, 9, 10, 25] as $n) {
    echo placing($n), PHP_EOL;
}

A notification sentence

Reads 'This is the third failed sign-in attempt on your account today.' The spelled form sits inside a sentence far better than '3rd', which reads as machine output in email copy.

Example · php
<?php

use Illuminate\Support\Number;

class FailedLoginNotification
{
    public function __construct(private int $attempt) {}

    public function toMail(): string
    {
        return sprintf(
            'This is the %s failed sign-in attempt on your account today.',
            Number::spellOrdinal($this->attempt)
        );
    }
}

echo (new FailedLoginNotification(3))->toMail(), PHP_EOL;

Checking locale support before relying on it

Comparing the two columns is the quickest way to spot a locale where %spellout-ordinal is missing: if the ordinal column matches the cardinal one, ICU fell back rather than applying an ordinal ruleset, and you should not ship that string.

Example · php
<?php

use Illuminate\Support\Number;

foreach (['en', 'fr', 'de', 'es'] as $locale) {
    printf(
        "%-3s cardinal: %-20s ordinal: %s\n",
        $locale,
        Number::spell(3, locale: $locale),
        Number::spellOrdinal(3, locale: $locale)
    );
}

Discussion

  • Be the first to comment on this lesson.