72

Is there a function that will express any given number in words?

For example:

If a number is 1432, then this function will return "One thousand four hundred and thirty two".

pigrammer
  • 2,603
  • 1
  • 11
  • 24
anita.kcx
  • 933
  • 2
  • 12
  • 18

4 Answers4

184

Use the NumberFormatter class that are in php ;)

$f = new NumberFormatter("en", NumberFormatter::SPELLOUT);
echo $f->format(1432);

That would output "one thousand four hundred thirty-two"

martindilling
  • 2,839
  • 3
  • 16
  • 13
  • 2
    It's part of the PECL intl extension – yitznewton Dec 28 '14 at 03:12
  • 15
    If you want a more verbose output use `$f->setTextAttribute(NumberFormatter::DEFAULT_RULESET, "%spellout-numbering-verbose");` which will output `one thousand four hundred and thirty-two` – Chris Wheeler Dec 31 '15 at 15:35
  • How does one get the PECL intl extension? Ubuntu PHP 7.2 server. Also is this still OK? It's maintenance stopped in 2013 with version 3.0.0 @yitznewton – s3c May 06 '20 at 11:17
  • Sorry, I switched companies and stopped using PHP right after I posted that comment, so I'm afraid I don't know anything about the current ecosystem – yitznewton May 27 '21 at 10:35
  • This "$f = new NumberFormatter("en", NumberFormatter::SPELLOUT);" is not working for me, any tips to make this work? I'm using MS Edge for this. – MJ DLS Oct 25 '21 at 01:19
  • It also handles decimals, e.g. 12.34 -> twelve point three four. – Yimin Rong Mar 31 '23 at 16:02
  • This solution not worked for me. getting error `NumberFormatter class not found`. Thanks dear. – Kamlesh Jun 22 '23 at 13:14
45

You can do this in many ways I am mentioning here two ways by using The NumberFormatter class as mentioned in Martindilling answer (if you have php version 5.3.0 or higher and also PECL extension 1.0.0 or higher) or by using the following custom function.

function convertNumberToWord($num = false)
{
    $num = str_replace(array(',', ' '), '' , trim($num));
    if(! $num) {
        return false;
    }
    $num = (int) $num;
    $words = array();
    $list1 = array('', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven',
        'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'
    );
    $list2 = array('', 'ten', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety', 'hundred');
    $list3 = array('', 'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion', 'sextillion', 'septillion',
        'octillion', 'nonillion', 'decillion', 'undecillion', 'duodecillion', 'tredecillion', 'quattuordecillion',
        'quindecillion', 'sexdecillion', 'septendecillion', 'octodecillion', 'novemdecillion', 'vigintillion'
    );
    $num_length = strlen($num);
    $levels = (int) (($num_length + 2) / 3);
    $max_length = $levels * 3;
    $num = substr('00' . $num, -$max_length);
    $num_levels = str_split($num, 3);
    for ($i = 0; $i < count($num_levels); $i++) {
        $levels--;
        $hundreds = (int) ($num_levels[$i] / 100);
        $hundreds = ($hundreds ? ' ' . $list1[$hundreds] . ' hundred' . ' ' : '');
        $tens = (int) ($num_levels[$i] % 100);
        $singles = '';
        if ( $tens < 20 ) {
            $tens = ($tens ? ' ' . $list1[$tens] . ' ' : '' );
        } else {
            $tens = (int)($tens / 10);
            $tens = ' ' . $list2[$tens] . ' ';
            $singles = (int) ($num_levels[$i] % 10);
            $singles = ' ' . $list1[$singles] . ' ';
        }
        $words[] = $hundreds . $tens . $singles . ( ( $levels && ( int ) ( $num_levels[$i] ) ) ? ' ' . $list3[$levels] . ' ' : '' );
    } //end for loop
    $commas = count($words);
    if ($commas > 1) {
        $commas = $commas - 1;
    }
    return implode(' ', $words);
}
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Shahbaz
  • 3,433
  • 1
  • 26
  • 43
  • 3
    Nice function, looks ok so far - note that `hundred` is always `hundred` and will not follow with an `s` – Onimusha Nov 07 '15 at 01:33
  • If it helps you you should vote up, but If you vote down please explain the reason! Thanks – Shahbaz Mar 02 '16 at 12:59
  • Nice function. But I think you should fix the "hundreds" thing. @Onimusha has also pointed this out. – Stephen Adelakun May 24 '17 at 19:32
  • thanks @StephenAdelakun for reminder but its just a variable the actual string used is hundred. – Shahbaz May 25 '17 at 05:16
  • 1
    it doesn't show the point part ..How do you concat that? – Hola Jun 15 '17 at 05:02
  • 1
    `return implode(' ', $words);` gave me a bunch of weird white space between and around words. This won't be noticeable if the strings are output to html of course, but for the OCD crowd you can use a regex and trim() to eliminate it. Replace that line with `return trim(preg_replace('~[\\s]+~', ' ', implode(' ', $words)));` – sfscs Nov 16 '19 at 04:04
  • When dealing large numbers larger dan int, use floor. `$num = floor($num);`. Wrong output when number is larger than 2billion – reignsly May 19 '20 at 11:22
  • I am looking solution like `BRUNEI DOLLARS THIRTY-FIVE THOUSAND SIX HUNDERED AND FORTY-TWO for 35,642.00`. any suggestion, please share – Kamlesh Jun 22 '23 at 13:18
13

Yes, http://www.karlrixon.co.uk/writing/convert-numbers-to-words-with-php/

However this is pretty dirty example. Please use NumberFormatter from intl (this will work from PHP 5.3)

$f = new NumberFormatter("in", NumberFormatter::SPELLOUT);
echo $f->format(123456);
Daniil Ryzhkov
  • 7,416
  • 2
  • 41
  • 58
  • 2
    I was just about to post the same link. It's in the first page of google results even. – Fluffeh Jul 16 '12 at 07:51
  • right now it displays '259833' as :-two hundred and fifty-nine thousand, eight hundred and thirty-three. I would like it to displayed as "Two lakhs fifty nine thousand eight hundred thirty three". – anita.kcx Jul 16 '12 at 08:15
  • Um, is that wrong? – Daniil Ryzhkov Jul 16 '12 at 08:16
  • no - How do I display it in Indian number format? – anita.kcx Jul 16 '12 at 08:17
  • change `100 => 'hundred'` to `100 => 'lakhs'` – Leysam Rosario Nov 14 '13 at 08:01
  • 1
    @LeysamRosario I think he will gonna have to do more than that. as in indian term there is hundred term for hundered, but when it comes to 0.1 Million , it is said to be 1 lakh, and 1 Million = Ten Lakh and 10 Million = One Carore. – Sizzling Code Nov 10 '15 at 09:13
  • @DaniilRyzhkov The link is dead, hence why I removed it. Also, by adding the broken link back in, you're putting yourself back in the crosshairs of [this meta discussion](http://meta.stackoverflow.com/questions/334866/cleanup-500-old-terse-answers-that-either-have-hidden-value-or-indicate-awful-qu) – Machavity Sep 21 '16 at 19:43
10

In case of using Yii2 you can do this as simple as the following:

$sum = 100500;
echo Yii::$app->formatter->asSpellout($sum);

This prints spelled out $sum in your app's language.

Docs reference

Alliswell
  • 1,523
  • 20
  • 35