fork download
  1. <?php
  2.  
  3. /* Возвращает соответствующую числу форму слова: 1 рубль, 2 рубля, 5 рублей */
  4. function inclineWord($number, $word1, $word2, $word5) {
  5.  
  6. if (preg_match('/(^1|[^1]1)$/', $number) == TRUE)
  7. return $word1;
  8. elseif (preg_match('/([^1][2-4])$/', $number) == TRUE) //в зависимости от последних знаков, подбирается подходящее слово
  9. return $word2;
  10. elseif (preg_match('/(.?[05-9]|1\d)$/', $number) == TRUE)
  11. return $word5;
  12. }
  13.  
  14. /*
  15.   Преобразует числа от 0 до 999 в текст. Параметр $isFemale равен нулю,
  16.   если мы считаем число для мужского рода (один рубль),
  17.   и 1 — для женского (одна тысяча)
  18. */
  19. function smallNumberToText($number, $isFemale) {
  20.  
  21. $spelling = array(
  22. 0 => 'ноль', 10 => 'десять', 100 => 'сто',
  23. 1 => 'один', 11 => 'одиннадцать', 20 => 'двадцать', 200 => 'двести',
  24. 2 => 'два', 12 => 'двенадцать', 30 => 'тридцать', 300 => 'триста',
  25. 3 => 'три', 13 => 'тринадцать', 40 => 'сорок', 400 => 'четыреста',
  26. 4 => 'четыре', 14 => 'четырнадцать', 50 => 'пятьдесят', 500 => 'пятьсот',
  27. 5 => 'пять', 15 => 'пятнадцать', 60 => 'шестьдесят', 600 => 'шестьсот',
  28. 6 => 'шесть', 16 => 'шестнадцать', 70 => 'семьдесят', 700 => 'семьсот',
  29. 7 => 'семь', 17 => 'семнадцать', 80 => 'восемьдесят', 800 => 'восемьсот',
  30. 8 => 'восемь', 18 => 'восемнадцать', 90 => 'девяносто', 900 => 'девятьсот',
  31. 9 => 'девять', 19 => 'девятнадцать', 'null' => '' /* null - специальный ключ на случай если нет необходимости писать прописью, к примеру, ноль тысяч */
  32. );
  33.  
  34. $femaleSpelling = array(
  35. 1 => 'одна', 2 => 'две'
  36. );
  37.  
  38. if ($isFemale == 1) //на случай, если речь зайдет о тысячах и нужно будет употребить 'одна', а не 'один'
  39. $spelling = array_replace($spelling, $femaleSpelling);
  40.  
  41. if (preg_match('/^(000)$/', $number) == TRUE) //если где-то в середине затерялось 3 нолика и их не нужно озвучивать
  42. $result = $spelling['null'];
  43. elseif (preg_match('/^(000)$/', $number) == FALSE) { //тут уже раскладываем число по словам
  44. settype($number, "integer"); //ибо для удобства числа в функцию залетают в виде строк, исправляем это
  45. $preparationArray = array(); //то, куда будем все складывать
  46.  
  47. if (array_key_exists($number, $spelling) == TRUE) { //в случае обнаружения входного числа в массиве
  48. $preparationArray[] = $spelling[$number];
  49. } elseif (array_key_exists($number, $spelling) == FALSE) { //тут сами раскладываем число
  50.  
  51. if ($number > 99) {
  52. $hundreds = floor($number / 100) * 100;
  53. $decades = $number % 100;
  54. $numbers = $decades % 10;
  55.  
  56. if (array_key_exists($decades, $spelling) == TRUE && $decades > 9) //не будем дописывать единицы в этом случае
  57. $numbers = 'null';
  58. elseif ($decades >= 0) { //расписываем десятки и числа сами
  59.  
  60. if (array_key_exists($decades, $spelling) == FALSE)
  61. $decades -= $numbers;
  62. elseif ($decades < 10)
  63. $decades = 'null';
  64. }
  65. } elseif ($number <= 99) {
  66. $nundreds = 'null';
  67. $decades = floor($number / 10) * 10;
  68. $numbers = $number - $decades;
  69.  
  70. if ($number < 10) //в случае если второй знак в номере будет меньше 1, десятки не прописываются
  71. $decades = 'null';
  72. }
  73. array_push($preparationArray, $spelling[$hundreds], $spelling[$decades], $spelling[$numbers]);
  74. $preparationArray = array_diff($preparationArray, array('')); //очищаем массив от пустых элементов, избегая лишних пробелов
  75. }
  76. $result = implode(' ', $preparationArray); //склеиваем элементы конечного массива слов пробелами
  77. }
  78. return $result;
  79. }
  80.  
  81. function numberToText($number) {
  82.  
  83. $preparationArray = array();
  84. $number = strval($number);
  85.  
  86. if ($number > 999999) {
  87. $millionsPrep = mb_substr($number, 0, -6);
  88. $millions = smallNumberToText($millionsPrep, 0) . ' ' . inclineWord($millionsPrep, 'миллион', 'миллиона', 'миллионов');
  89. $preparationArray[] = $millions;
  90. }
  91.  
  92. if ($number > 999) {
  93. $thousandsPrep = mb_substr($number, -6, -3);
  94. if (intval($thousandsPrep) > 0) { //если тысяч будет больше, чем 0, то мы выведем слова, а иначе зачем это делать?
  95. $thousands = smallNumberToText($thousandsPrep, 1) . ' ' . inclineWord($thousandsPrep, 'тысяча', 'тысячи', 'тысяч');
  96. $preparationArray[] = $thousands;
  97. }
  98. }
  99.  
  100. if ($number >= 0) {
  101. if ($number > 999) {
  102. $numbersPrep = mb_substr($number, -3);
  103. } elseif ($number <= 999) {
  104. $numbersPrep = $number;
  105. }
  106. $numbers = smallNumberToText($numbersPrep, 0) . ' ' . inclineWord($numbersPrep, 'рубль', 'рубля', 'рублей') . ' ' . "({$number})";
  107. $preparationArray[] = $numbers;
  108. }
  109. $result = implode(' ', $preparationArray);
  110. return $result;
  111. }
  112.  
  113.  
  114. /* Вызовем функцию несколько раз */
  115. $amount1 = 4160;
  116. $text1 = numberToText($amount1);
  117.  
  118. echo "На вашем счету {$text1}\n";
Success #stdin #stdout 0.02s 24764KB
stdin
Standard input is empty
stdout
На вашем счету четыре  сто шестьдесят рублей (4160)