<?php

error_reporting(-1);

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

    if ($number % 100 > 10 and $number % 100 < 20) {
        $number %= 100;
    } elseif ($number > 0) {
        $number %= 10;
    }

    if ($number == 1) {
        $word = $word1;
    } elseif ($number >= 2 and $number <= 4) {
        $word = $word2;
    } elseif ($number >= 5 and $number <= 9 or $number > 10 and $number < 20 or $number == 0) {
        $word = $word3;
    }

    return $word;
}

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

    $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  =>  'девятнадцать'    
    );

    if ($isFemale) {
        $femaleSpelling = array(
            1   =>  'одна',  
            2   =>  'две'
        );
        $spelling = array_replace($spelling, $femaleSpelling);
    }
    
    if ($number > 0) {

	    $lengthOfNumber = floor(log10($number) + 1);
	    
	    // Разделение числа на единичный массив
	    for ($i = 0; $i < $lengthOfNumber; $i++) {
            // Объединение чисел с особой формой
	        if ($i == 0 and $number % 100 > 10 and $number % 100 < 20) {
	            $numbers[] = ($number % 100);
	            $number = floor($number / 100);
	        } else {
	            $numbers[] = ($number % 10);
	            $number = floor($number / 10);
	        }
	    }
	    
	    $numbers = array_reverse($numbers);
	    $arraySize = count($numbers);
        /*
        Подбор множителя, с его помощью из словаря запрашиваются сотни/десятки.

        Например, если размер ранее полученного массива с числами равен двум 
        и длина числа тоже равна двум, то множитель устанавливает значение 10.
        В цикле, которой следует ниже, после итерации множитель уменьшается до 1.
        */
	    $mult = ($arraySize > 1) ? (($lengthOfNumber == 3) ? 100 : 10) : 1;

        /* Берет по порядку значения из массива, делает запрос в словарь 
        и записывает полученное текстовое значение в массив $words */
	    for ($i = 0; $i < $arraySize; $i++) {
	        if ($numbers[$i] != 0) {
	            $words[] = $spelling[$numbers[$i] * $mult];
	        }
            // Уменьшение множителя для следующей итерации
	        $mult = ($lengthOfNumber == 3 and $arraySize == 2) ? 1 : $mult / 10;
	    }
	
	    $text = implode(' ', $words);

    } elseif ($totalNumberLength < 1) {
        $text = $spelling[$number];
    } else {
        $text = null;
    }

    return $text;
}

function numberToText($number) {

    $spelling = array(
        0 => array(0 => 'рубль', 1 => 'рубля', 2 => 'рублей'),
        1 => array(0 => 'тысяча', 1 => 'тысячи', 2 => 'тысяч'),
        2 => array(0 => 'миллион', 1 => 'миллиона', 2 => 'миллионов')
    );
    
    $lengthOfNumber = floor(log10($number) + 1);

    $divisibleNumber = $number;
    // Цикл выполняется N-е кол-во раз в зависимости от длины числа или один раз для обработки нуля
    for ($x = 0; $x < ceil($lengthOfNumber / 3) or $x == 0; $x++) {

        // Делит число на массив по три единицы
        $numbers[] = $divisibleNumber % 1000;
        $divisibleNumber = floor($divisibleNumber / 1000);

        // Берет от тысячного числа в массиве $numbers последнюю цифру и проверяет на женственный род
        $isFemale = ($x == 1 and $numbers[1] % 10 == 1 or $x == 1 and $numbers[1] % 10 == 2) ? 1 : 0;

        $numberInText = smallNumberToText($numbers[$x], $isFemale, $lengthOfNumber);
        $inclinedWord = inclineWord($numbers[$x], $spelling[$x][0], $spelling[$x][1], $spelling[$x][2]);

        // Формирование и запись результата
        if ($x == 0) {
            if ($numberInText) {
                $text = $numberInText;
            }
            if (isset($text)) {
                $text = $text.' '."($number)".' '.$inclinedWord;
            } else {
                $text = "($number)".' '.$inclinedWord;
            }
        } else {
            if ($numberInText) {
                $text = $numberInText.' '.$inclinedWord.' '.$text;
            }
        }
    }

    return $text;
}

/* Вызовем функцию несколько раз */

$amount1 = mt_rand(1,99999999);
$text1 = numberToText($amount1);
 
echo "На вашем счету {$text1}\n";
 
$amount2 = mt_rand(1,99999999);
$text2 = numberToText($amount2);
 
echo "На вашем счету {$text2}\n";
 
$amount3 = mt_rand(1,99999999);
$text3 = numberToText($amount3);
 
echo "На вашем счету {$text3}\n";

$numbers = [999999999, 0, 1, 11012013, 7000008, 1002, 1000, 7000000];
foreach ($numbers as $number) {
    $amount4 = $number;
    $text4 = numberToText($amount4);
     
    echo "На вашем счету {$text4}\n";
}