All guides
No guide matches your search.
Number to words
Spell integers out in Persian (up to 10^21) and Arabic (up to 10^27), and read Persian number words back into numbers with fromWords().
On this page
Converting numbers to words
NumberToWords::convert() spells an integer out as words. Persian (fa) is the default and covers every integer below 1021.
<?php
require 'vendor/autoload.php';
use RtlyKit\Number\NumberToWords;
use function RtlyKit\number_to_words;
echo NumberToWords::convert(0), "\n"; // صفر
echo NumberToWords::convert(21), "\n"; // بیست و یک
echo NumberToWords::convert(115), "\n"; // صد و پانزده
echo NumberToWords::convert(1001), "\n"; // یک هزار و یک
echo NumberToWords::convert(12345), "\n"; // دوازده هزار و سیصد و چهل و پنج
echo NumberToWords::convert(-45), "\n"; // منفی چهل و پنج
echo number_to_words(2000000000), "\n"; // دو میلیارد
echo NumberToWords::convert(1234567), "\n";
// یک میلیون و دویست و سی و چهار هزار و پانصد و شصت و هفتWords are joined with « و » (and) between all parts. Each scale word follows its group: «هزار» (103), «میلیون» (106), «میلیارد» (109), «تریلیون» (1012), «کوادریلیون» (1015) and «کوینتیلیون» (1018). A group equal to 1 keeps its «یک», so 1000 is «یک هزار». To read a bare «هزار», use fromWords() below. Zero groups are skipped.
Accepted input
The parameter is typed int|float|string:
- int: the whole PHP range works, including
PHP_INT_MAX: «نه کوینتیلیون و دویست و بیست و سه کوادریلیون ...». - float: must be finite and whole.
3.0gives «سه».1.5throws and is not silently cut. - string: an optional sign and digits in any digit set. Commas,
٬and spaces are removed, so a number copied from a form works. Strings can be longer than a PHP int, up to 21 digits after leading zeros are dropped.
echo NumberToWords::convert('۱۲۳٬۴۵۶'), "\n"; // صد و بیست و سه هزار و چهارصد و پنجاه و شش
echo NumberToWords::convert('1,000,000'), "\n"; // یک میلیون
echo NumberToWords::convert('+7'), "\n"; // هفت
echo NumberToWords::convert('-0'), "\n"; // صفر
echo NumberToWords::convert('999999999999999999999'), "\n";
// نهصد و نود و نه کوینتیلیون و نهصد و نود و نه کوادریلیون ... و نهصد و نود و نهErrors
Invalid input throws InvalidNumberException, a subclass of RtlyKitException. Read the stable code with getErrorCode():
| Input | Error code |
|---|---|
1.5, '12a', '' | invalid_number |
NAN, INF | non_finite_number |
| A string longer than 4096 bytes | input_too_long |
1e21, '1000000000000000000000' (22 digits) | number_too_large |
try {
NumberToWords::convert('1000000000000000000000');
} catch (\RtlyKit\Exceptions\InvalidNumberException $e) {
echo $e->getMessage(), ' [', $e->getErrorCode()->value, "]\n";
// Number is too large (limit is 10^21 - 1). [number_too_large]
}See Error handling to catch every library exception with one type.
Arabic
Pass 'ar' as the second argument for Modern Standard Arabic. The locale is matched on its first two letters, ignoring case. So 'ar_SA' and 'AR' work, and 'fa_IR' works for Persian.
echo NumberToWords::convert(11, 'ar'), "\n"; // أحد عشر
echo NumberToWords::convert(21, 'ar'), "\n"; // واحد وعشرون
echo NumberToWords::convert(200, 'ar'), "\n"; // مئتان
echo NumberToWords::convert(3000, 'ar'), "\n"; // ثلاثة آلاف
echo NumberToWords::convert(2000000, 'ar'), "\n"; // مليونان
echo NumberToWords::convert(1002003, 'ar'), "\n"; // مليون وألفان وثلاثة
echo NumberToWords::convert(-7, 'ar'), "\n"; // سالب سبعةWithout options, the Arabic output is the bare counting form (masculine, nominative, no vowel marks). The range is every integer below 1027, and negative numbers start with «سالب». A larger number throws number_too_large.
When a counted noun follows the number, you can ask for gender, grammatical case, vowel marks, other spellings of «مئة» and more. The new ArabicOptions and the Arabic ordinals (first to ninety-ninth) have their own page: Arabic number words.
An unsupported locale throws UnsupportedLocaleException with the code unsupported_locale:
try {
NumberToWords::convert(5, 'en');
} catch (\RtlyKit\Exceptions\UnsupportedLocaleException $e) {
echo $e->getMessage(), "\n"; // Unsupported locale 'en' (use 'fa' or 'ar').
}From words back to a number
NumberToWords::fromWords() is the reverse of the Persian conversion for the forms convert() produces. It returns an int when the value fits in a PHP int, and a digit string otherwise.
var_dump(NumberToWords::fromWords('بیست و سه')); // int(23)
var_dump(NumberToWords::fromWords('منفی چهل و دو')); // int(-42)
var_dump(NumberToWords::fromWords('هزار و یک')); // int(1001)
var_dump(NumberToWords::fromWords('دو میلیون و سیصد هزار و پنج')); // int(2300005)
// Round trip across the whole range:
var_dump(NumberToWords::fromWords(NumberToWords::convert(PHP_INT_MAX)));
// int(9223372036854775807)
var_dump(NumberToWords::fromWords(NumberToWords::convert('999999999999999999999')));
// string(21) "999999999999999999999"How words are read
- The input is cleaned first. Arabic letter variants become Persian («ك» to «ک», «ي» to «ی»), a ZWNJ counts as a space, and extra whitespace is ignored.
- A leading «منفی» makes the result negative. «منفی صفر» is
0. - A scale word with no number before it means one, so «هزار» is 1000.
- Scales must go from large to small. «هزار هزار» and «هزار میلیون» throw.
- Inside a group the order is hundreds, then tens, then units. A single word from «ده» to «نوزده» can stand in for tens and units. «دو صد», «پنج و بیست» and «یازده و یک» throw.
- The word «و» is required between every two number words. The one pair written without it is a multiplier and its scale word, as in «دو هزار». A «و» at the start, at the end, doubled or next to a scale word is rejected.
- «صفر» is accepted only on its own, or after «منفی».
try {
NumberToWords::fromWords('یکصد');
} catch (\RtlyKit\Exceptions\InvalidNumberException $e) {
echo $e->getMessage(), ' [', $e->getErrorCode()->value, "]\n";
// Unknown number word 'یکصد'. [invalid_number_words]
}Errors carry the code invalid_number_words (unknown word, wrong sequence, scales out of order, empty text) or input_too_long for text over 4096 bytes.
Good to know. fromWords() reads only the canonical word order. A phrase like «دو صد» (which a lenient reader would turn into 102), «بیست یک» or a stray «و» at the end throws InvalidNumberException with the code invalid_number_words. Every string that convert() produces is read back unchanged, and a bare scale word at the start («هزار و یک») is allowed. Only the Persian form is read. Arabic words from convert($n, 'ar'), ordinals such as «سیام» and the compact spelling «یکصد» are not understood and throw.
Was this page helpful?