Вы здесь

PHP функция, для получения суммы прописью

tags: 

Знаю что эта тема уже поднималась, но предложенный вариант, также как и функция которой я пользовался до этого, оставляли чувство что задачу можно решить проще и элегантнее. Поэтому я сел, проанализировал задачу и написал еще один велосипед вариант. В результате у меня получилось две функции. В класс я их не стал заворачивать, чтобы они пригодились и тем кто сидит на php4 и те кто на php5.

Вы спросите — зачем? я пытался добиться простоты и прозрачности реализации. В итоге, как мне показалось, у меня получилось достаточно простая структура
— подготовка массивов с данными
— нормализация входного значения
— обработка этого значения
num2str(878867.15);

выведет:

восемьсот семьдесят восемь тысяч восемьсот шестьдесят семь рублей пятнадцать копеек

Далее сам код…

<?php
function num2str($inn=0) {
    
$o  = array(); // Результаты
    
$str= array(); // Основные массивы с строками
    
$str[0] = array('','сто','двести','триста','четыреста','пятьсот','шестьсот','семьсот''восемьсот','девятьсот','тысяча');
    
$str[1] = array('','десять','двадцать','тридцать','сорок','пятьдесят','шестьдесят''семьдесят','восемьдесят','девяносто','сто');
    
// названия чисел для сущностей женского рода
    
$str[2] = array('','один','два','три','четыре','пять','шесть''семь','восемь','девять','десять');
    
// названия чисел для сущностей мужского рода
    
$str[3] = array('','одна','две','три','четыре','пять','шесть''семь','восемь','девять','десять');
    
$str11  = array(11=>'одиннадцать',12=>'двенадцать',13=>'тринадцать',14=>'четырнадцать'
        
15=>'пятнадцать',16=>'шестнадцать',17=>'семнадцать'18=>'восемнадцать',19=>'девятнадцать',20=>'двадцать');
    
$forms = array(
        
//     1          2,3,4       5...        род слова(индекс для $str )
        
array('копейка''копейки',  'копеек',    3),
        array(
'рубль',   'рубля',    'рублей',    2),    // 10^0
        
array('тысяча',  'тысячи',   'тысяч',     3),    // 10^3
        
array('миллион''миллиона''миллионов'2),    // 10^6
        
array('миллиард','миллиарда','миллиардов',2),    // 10^9
        
array('триллион','триллиона','триллионов',2),    // 10^12
        // можно дописать всякие секстилионы ...
    
);

    

// Нормализация значения, избавляемся от ТОЧКИ, например 6754321.67 переводим в 7654321067
    
$tmp explode('.'str_replace(',','.'$inn));
    
$rub $tmp[0]; // рубли
    
$kop = isset($tmp[1]) ? str_pad(str_pad($tmp[1], 2'0'), 3'0',STR_PAD_LEFT) : '000'// копейки
    
$rub .= $kop// нормализованное значение

    // Поехали!
    

$levels explode('-'number_format($rub,0,'','-') );
    
$offset sizeof($levels)-1;
    foreach(
$levels as $k=>$level) {
        
$index $offset-$k;
        
$level str_pad($level3'0'STR_PAD_LEFT);
        if (!empty(
$str[0][$level[0]])) $o[] = $str[0][$level[0]];
        
$tmp intval($level[1].$level[2]);
        if (
$tmp>20) {
            
$tmp strval($tmp);
            for(
$i=0,$m=strlen($tmp); $i<$m$i++) {
                
// $forms[$index][3] - род слова для текущего уровня
                
$rod $forms[$index][3];
                
$tmp_o = ($i+1)==$str[$rod][$tmp[$i]] : $str[$i+1][$tmp[$i]];
                if (!empty(
$tmp_o)) $o[]= $tmp_o;
            }
        }
        else {
            
$o[] = ($tmp>10 $str11[$tmp] : $str[$forms[$index][3]][$tmp] );
        }
        
$tmp_o pluralForm($level$forms[$index][0], $forms[$index][1] ,$forms[$index][2] );
        if (!empty(
$tmp_o)) $o[] = $tmp_o;
    }
    if (
'000'==$kop) { // Если ноль копеек
        
$o[] = '00';
        
$o[] = $forms[0][2];
    }
    return 
implode(' ',$o);
}

function 

pluralForm($n$f1$f2$f5) {
    if (
intval($n)==0)
        return 
'';
    
$n abs($n) % 100;
    
$n1 $n 10;
    if (
$n 10 && $n 20) return $f5;
    if (
$n1 && $n1 5) return $f2;
    if (
$n1 == 1) return $f1;
    return 
$f5;
}
?>

Оригинал статьи: http://habrahabr.ru/blogs/php/53210/.