Spell Out Numbers PHP Function

Spelled out numbers can make automatically formatting your pages difficult. PHP has a great built-in function for spelling out dates, but none for standalone numbers. So I decided to build one. Here’s a working example of my function that converts numeric digits to spelled out words:

Depending on the style guide that your website follows, the number at which you should stop spelling out words will vary. According to the AP Stylebook, only numbers less than 10 should be spelled out. The Chicago Manual of Style, on the other hand, says that anything less than 101 should be. Which is right? That depends where you’re writing. Consistency is important, so most publications have their own style guidelines. If the one you’re working for doesn’t, you’re free to choose for yourself. Just be sure to be consistent.

Quick side note… There are plenty of exceptions to the basic rules mentioned in the previous paragraph. Years, numbers at the start of a sentence, decimals, etc. can throw you a curveball, so be sure to check with your style guide for anything out of the ordinary.

Now that we have that out of the way, let’s get to the function. It’s purpose is to let you easily go from the digits to the words in the middle of a paragraph or list. It includes the ability to include minimum and maximum arguments, so that you can easily set it to follow AP or Chicago style — or your own custom style. Without the max set, it’ll handle numbers up to one less than a quadrillion. (That’s nine hundred ninety-nine trillion nine hundred ninety-nine billion nine hundred ninety-nine million nine hundred ninety-nine thousand nine hundred ninety-nine in spelled out form.)

Whoa! That’s a lot of words with no commas! True, but that’s intentional. According to Chicago, “No commas should be used when numbers are written out… The longer the number, the more awkward it may seem, but commas would make the number look like a series of smaller numbers, something that doesn’t happen with numerals because there are no spaces, for one thing.”

Another note is that this tool is, obviously, in English. And, more specifically, it’s in American English. Up until fairly recently, British and American words for numbers 1,000,000,000 and greater differed. Confusing? Very. Luckily, everyone (including this function) is using the American system now.

Below is the function itself. I have it saved it a separate file and then use require_once to include it whenever it’s needed.

<?php

function spellnumber($x,$min=0,$max=100) {
	if (!preg_match('/^-?([0-9]{1,15})(\.[0-9]+)?$/',$x)) { return $x; } //if not a number less than a quadrillion, leave it alone
	elseif (strpos($x,'.') !== false) { list($int,$dec) = explode('.',$x); return number_format($int).'.'.$dec; } //if not an intenger
	elseif (($min !== false) && ($x < $min)) { return number_format($x); } //return numeral if less than minimum
	elseif (($max !== false) && ($x > $max)) { return number_format($x); } //return numeral if greater than maximum
	
	if ($x < 0) { $w = 'negative '; $x = abs($x); } else { $w = ''; } //check to see if it's negative

	if ($x < 20) { return $w.spellnumber_under20($x); } //shortcut for small numbers

	$d = str_split($x); //explode the number into an array of single digits
	$d = array_reverse($d); //reverse so that we can work from the right
	
	//trillions
	if (array_key_exists('12',$d)) {
		$t = floor($x/1000000000000);
		if ($t > 0) { $w .= spellnumber($t,0,999).' trillion '; }
		$x = $x - ($t * 1000000000000);
	}

	//billions
	if (array_key_exists('9',$d)) {
		$t = floor($x/1000000000);
		if ($t > 0) { $w .= spellnumber($t,0,999).' billion '; }
		$x = $x - ($t * 1000000000);
	}
	
	//millions
	if (array_key_exists('6',$d)) {
		$t = floor($x/1000000);
		if ($t > 0) { $w .= spellnumber($t,0,999).' million '; }
		$x = $x - ($t * 1000000);
	}

	//thousands
	if (array_key_exists('3',$d)) {
		$t = floor($x/1000);
		if ($t > 0) { $w .= spellnumber($t,0,999).' thousand '; }
	}

	//third-to-last digit
	if (array_key_exists('2',$d)) {
		if ($d['2'] == 1) { $w .= 'one hundred '; }
		elseif ($d['2'] == 2) { $w .= 'two hundred '; }
		elseif ($d['2'] == 3) { $w .= 'three hundred '; }
		elseif ($d['2'] == 4) { $w .= 'four hundred '; }
		elseif ($d['2'] == 5) { $w .= 'five hundred '; }
		elseif ($d['2'] == 6) { $w .= 'six hundred '; }
		elseif ($d['2'] == 7) { $w .= 'seven hundred '; }
		elseif ($d['2'] == 8) { $w .= 'eight hundred '; }
		elseif ($d['2'] == 9) { $w .= 'nine hundred '; }
	}

	$last2 = round($d['1'].$d['0']); //combine the last 2 digits and handle them together
	if ($last2 < 20) {
		if ($last2 > 0) { $w .= spellnumber_under20($last2); }
	} else {
		//second-to-last digit
		if ($d['1'] == 2) { $w .= 'twenty'; }
		elseif ($d['1'] == 3) { $w .= 'thirty'; }
		elseif ($d['1'] == 4) { $w .= 'forty'; }
		elseif ($d['1'] == 5) { $w .= 'fifty'; }
		elseif ($d['1'] == 6) { $w .= 'sixty'; }
		elseif ($d['1'] == 7) { $w .= 'seventy'; }
		elseif ($d['1'] == 8) { $w .= 'eighty'; }
		elseif ($d['1'] == 9) { $w .= 'ninety'; }

		//last digit
		if ($d['0'] != 0) {
			if ($d['1'] >= 2) { $w .= '-'; } //if 20 or more
			$w .= spellnumber_under20($d['0']);
		}
	}
	
	return $w;
}

//this next function does not have any input verification. it should only be called from within the main spellnumber function
function spellnumber_under20($x) {
	switch($x) {
		case 0; return 'zero';
		case 1; return 'one';
		case 2; return 'two';
		case 3; return 'three';
		case 4; return 'four';
		case 5; return 'five';
		case 6; return 'six';
		case 7; return 'seven';
		case 8; return 'eight';
		case 9; return 'nine';
		case 10; return 'ten';
		case 11; return 'eleven';
		case 12; return 'twelve';
		case 13; return 'thirteen';
		case 14; return 'fourteen';
		case 15; return 'fifteen';
		case 16; return 'sixteen';
		case 17; return 'seventeen';
		case 18; return 'eighteen';
		case 19; return 'nineteen';
	}
	return $x; //just in case
}

?>

I have quite a few inline comments in there, so hopefully it’s easy to follow along with what’s happening. A few notes, though:

  • The function defaults to Chicago style, spelling out numbers one hundred and smaller. To adjust that, pass numbers or false for the $min and $max arguments.
  • Setting the minimum to 0 is different from leaving it false. If 0, any negative numbers will be returned in numeric form, not spelled out.
  • Don’t call the spellnumber_under20 function directly; it doesn’t have any input verification on it. (This is for performance reasons.)
  • Numbers with decimal points (even if 0 is after the decimal) and numbers that exceed the $min/$max limits are returned after being cleaned up by the number_format function. If you don’t want that to happen, edit lines 5 through 7.
  • Everything comes out lowercase, but you can use ucfirst or ucwords to easily change that.

There’s a mini-form at the top of this article where you can test out the function. (It has both $min and $max set to false.) Additionally, here are a few examples:

spellnumber(0,false,false); // zero
spellnumber(0,0,100); // zero

spellnumber(1,false,false); // one
spellnumber(1,0,100); // one

spellnumber(4,false,false); // four
spellnumber(4,0,100); // four

spellnumber(5,false,false); // five
spellnumber(5,0,100); // five

spellnumber(46,false,false); // forty-six
spellnumber(46,0,100); // forty-six

spellnumber(-57,false,false); // negative fifty-seven
spellnumber(-57,0,100); // -57

spellnumber(100,false,false); // one hundred 
spellnumber(100,0,100); // one hundred 

spellnumber(106,false,false); // one hundred six
spellnumber(106,0,100); // 106

spellnumber(110,false,false); // one hundred ten
spellnumber(110,0,100); // 110

spellnumber(231,false,false); // two hundred thirty-one
spellnumber(231,0,100); // 231

spellnumber(-346,false,false); // negative three hundred forty-six
spellnumber(-346,0,100); // -346

spellnumber(3.2,false,false); // 3.2
spellnumber(3.2,0,100); // 3.2

spellnumber(1234.2,false,false); // 1,234.2
spellnumber(1234.2,0,100); // 1,234.2

spellnumber(32332,false,false); // thirty-two thousand three hundred thirty-two
spellnumber(32332,0,100); // 32,332

spellnumber(234000,false,false); // two hundred thirty-four thousand 
spellnumber(234000,0,100); // 234,000

spellnumber(1000000000,false,false); // one billion 
spellnumber(1000000000,0,100); // 1,000,000,000

spellnumber(5159780352,false,false); // five billion one hundred fifty-nine million seven hundred eighty thousand three hundred fifty-two
spellnumber(5159780352,0,100); // 5,159,780,352

spellnumber(8675309,false,false); // eight million six hundred seventy-five thousand three hundred nine
spellnumber(8675309,0,100); // 8,675,309

spellnumber(999999999999999,false,false); // nine hundred ninety-nine trillion nine hundred ninety-nine billion nine hundred ninety-nine million nine hundred ninety-nine thousand nine hundred ninety-nine
spellnumber(999999999999999,0,100); // 999,999,999,999,999

spellnumber(1000000000000000,false,false); // 1000000000000000
spellnumber(1000000000000000,0,100); // 1000000000000000

That should be enough to give you an idea of how it works. If not, download the function and play around with it yourself.

If you have questions — or suggestions for improvement — please chime in via the comments below.


Comments

Loading…

This post was published on September 15th, 2015 by Robert James Reese in PHP. Before using any of the code or other content in this post, you must read and agree to our terms of use.