<?php

/* Возвращает соответствующую числу форму слова: 1 рубль, 2 рубля, 5 рублей */
function inclineWord($number, $word1, $word2, $word5) {

    if (preg_match('/(^1|[^1]1)$/', $number) == TRUE)
        return $word1;
    elseif (preg_match('/([^1][2-4])$/', $number) == TRUE) //в зависимости от последних знаков, подбирается подходящее слово
        return $word2;
    elseif (preg_match('/(.?[05-9]|1\d)$/', $number) == TRUE)
        return $word5;
}

/* 
    Преобразует числа от 0 до 999 в текст. Параметр $isFemale равен нулю, 
    если мы считаем число для мужского рода (один рубль), 
    и 1 — для женского (одна тысяча) 
*/
function smallNumberToText($number, $isFemale) {

    $spelling = array(
        0   =>  'ноль',                                     10  =>  'десять',       100 =>  'сто',
        1   =>  'один',         11  =>  'одиннадцать',      20  =>  'двадцать',     200 =>  'двести',
        2   =>  'два',          12  =>  'двенадцать',       30  =>  'тридцать',     300 =>  'триста',
        3   =>  'три',          13  =>  'тринадцать',       40  =>  'сорок',        400 =>  'четыреста',
        4   =>  'четыре',       14  =>  'четырнадцать',     50  =>  'пятьдесят',    500 =>  'пятьсот',
        5   =>  'пять',         15  =>  'пятнадцать',       60  =>  'шестьдесят',   600 =>  'шестьсот',
        6   =>  'шесть',        16  =>  'шестнадцать',      70  =>  'семьдесят',    700 =>  'семьсот',    
        7   =>  'семь',         17  =>  'семнадцать',       80  =>  'восемьдесят',   800 =>  'восемьсот',
        8   =>  'восемь',       18  =>  'восемнадцать',     90  =>  'девяносто',     900 =>  'девятьсот',
        9   =>  'девять',       19  =>  'девятнадцать',      'null' => ''                                                                   /* null - специальный ключ на случай если нет необходимости писать прописью, к примеру, ноль тысяч  */
    );
    
    $femaleSpelling = array(
        1   =>  'одна',        2   =>  'две'
    );
    
    if ($isFemale == 1) //на случай, если речь зайдет о тысячах и нужно будет употребить 'одна', а не 'один'
        $spelling = array_replace($spelling, $femaleSpelling);

    if (preg_match('/^(000)$/', $number) == TRUE) //если где-то в середине затерялось 3 нолика и их не нужно озвучивать
        $result = $spelling['null'];
    elseif (preg_match('/^(000)$/', $number) == FALSE) { //тут уже раскладываем число по словам
        settype($number, "integer"); //ибо для удобства числа в функцию залетают в виде строк, исправляем это
        $preparationArray = array(); //то, куда будем все складывать

        if (array_key_exists($number, $spelling) == TRUE) { //в случае обнаружения входного числа в массиве
            $preparationArray[] = $spelling[$number];
        } elseif (array_key_exists($number, $spelling) == FALSE) { //тут сами раскладываем число

            if ($number > 99) {
                $hundreds = floor($number / 100) * 100;
                $decades = $number % 100;
                $numbers = $decades % 10;

                if (array_key_exists($decades, $spelling) == TRUE && $decades > 9) //не будем дописывать единицы в этом случае
                    $numbers = 'null';
                elseif ($decades >= 0) { //расписываем десятки и числа сами

                    if (array_key_exists($decades, $spelling) == FALSE)
                        $decades -= $numbers;
                    elseif ($decades < 10)
                           $decades = 'null';
                }
            } elseif ($number <= 99) {
                $nundreds = 'null';     
                $decades = floor($number / 10) * 10;
                $numbers = $number - $decades;

                if ($number < 10) //в случае если второй знак в номере будет меньше 1, десятки не прописываются
                    $decades = 'null';
            } 
            array_push($preparationArray, $spelling[$hundreds], $spelling[$decades], $spelling[$numbers]);
            $preparationArray = array_diff($preparationArray, array('')); //очищаем массив от пустых элементов, избегая лишних пробелов
        }
        $result = implode(' ', $preparationArray); //склеиваем элементы конечного массива слов пробелами
    }
    return $result;
}

function numberToText($number) {
    
    $preparationArray = array();
    $number = strval($number);

    if ($number > 999999) {
        $millionsPrep = mb_substr($number, 0, -6);
        $millions = smallNumberToText($millionsPrep, 0) . ' ' . inclineWord($millionsPrep, 'миллион', 'миллиона', 'миллионов');
        $preparationArray[] = $millions;
    }

    if ($number > 999) {
        $thousandsPrep = mb_substr($number, -6, -3); 
        if (intval($thousandsPrep) > 0) { //если тысяч будет больше, чем 0, то мы выведем слова, а иначе зачем это делать?
            $thousands = smallNumberToText($thousandsPrep, 1) . ' ' . inclineWord($thousandsPrep, 'тысяча', 'тысячи', 'тысяч');
            $preparationArray[] = $thousands;
        }       
    }

    if ($number >= 0) {
        if ($number > 999) {
            $numbersPrep = mb_substr($number, -3);
        } elseif ($number <= 999) {
            $numbersPrep = $number;
        }
        $numbers = smallNumberToText($numbersPrep, 0) . ' ' . inclineWord($numbersPrep, 'рубль', 'рубля', 'рублей') . ' ' .  "({$number})";
        $preparationArray[] = $numbers;
    }
    $result = implode(' ', $preparationArray);
    return $result;
}


/* Вызовем функцию несколько раз */
$amount1 = 999999999;
$text1 = numberToText($amount1);
 
echo "На вашем счету {$text1}\n";
 
$amount2 = 0;
$text2 = numberToText($amount2);
 
echo "На вашем счету {$text2}\n";
 
$amount3 = 1;
$text3 = numberToText($amount3);
 
echo "На вашем счету {$text3}\n";
 
$amount4 = 11012013;
$text4 = numberToText($amount4);
 
echo "На вашем счету {$text4}\n";

$amount5 = 7000008;
$text5 = numberToText($amount5);
 
echo "На вашем счету {$text5}\n";

$amount6 = 1002;
$text6 = numberToText($amount6);
 
echo "На вашем счету {$text6}\n";

$amount7 = 1000;
$text7 = numberToText($amount7);
 
echo "На вашем счету {$text7}\n";

$amount8 = 7000000;
$text8 = numberToText($amount8);
 
echo "На вашем счету {$text8}\n";