金额从数字转换成中文汉字大写的实现

以下简单封装的实现方法,详细见注释

class money2chinese {
    private $amount; // 金额
    private $num2chinese; // 大写数字
    private $num_company; // 数字单位
    private $RMBunit; // 金额单位
    public function __construct($amount) {
        $amount=trim($amount);
        if (is_numeric($amount)){
            $this->amount=$amount;
        }else{
            exit('Please enter the correct number.');
        }
        $this->num2chinese = array (
                '零',
                '壹',
                '贰',
                '叁',
                '肆',
                '伍',
                '陆',
                '柒',
                '捌',
                '玖' 
        ); // 数字相对应的汉字
        $this->num_company = array (
                '拾',
                '佰',
                '仟',
                '万',
                '拾',
                '佰',
                '仟',
                '亿' 
        ); // 汉字位数
        $this->RMBunit = array (
                '圆',
                '角',
                '分' 
        ); // 金额单位
    }
    private function checkisfloat($cN,$num){
//      $cN = count ( $num );//$cN为1指没有小数,为2则有小数
        if ($cN > 1) {
            $k [0] = strlen ( $num [0] ); // 整数位的长度
            $k [1] = strlen ( $num [1] ); // 小数位的长度
            if ($k[1]>2){
                $num[1]=substr($num[1], 0,2);
                $k[1]=2;
            }
        } else {
            $k [0] = strlen ( $num [0] ); // 整数位的长度
        }
        return $k;
    }
    private function num2chinese($num,$cN,$k){
        $numtoChinese = array (); // 数字转换成汉字后的变量
        for($i = 0; $i < $cN; $i ++) { // 将金额的每一位数转换成相应的大写汉字,注意其位数是从个十百千...
            $n = $num [$i];
            for($j = 0; $j < $k [$i]; $j ++) {
                $flag = $n % 10;//取余
                $n = floor ( $n / 10 );//重新给$n赋值
                $numtoChinese [$i] [$j] = $this->num2chinese [$flag];
            }
        }
        return $numtoChinese;
    }
    private function dec2chinese($numtoChinese,$cN,$k){//小数位汉化
        /* 小数位 */
        if ($cN>1) {
            switch ($k[1]){
                case 1:
                    $decStr=$numtoChinese[1][0].$this->RMBunit[1];//小数汉字化完成
                    break;
                case 2:
                    $decStr=$numtoChinese[1][1].$this->RMBunit[1].$numtoChinese[1][0].$this->RMBunit[2];
                    break;
            }
        }
        return $decStr;//返回已经完成汉化的小数位
    }
    private function int2chinese($numtoChinese){//整数位汉化
        /* 整数位*/
        /*在每整数的每个字之间插入一个符号,如逗号,然后将其替换成相应位数 */
        $str = implode ( '.,.', $numtoChinese [0] );
        $intAmount = explode ( '.', $str );
        $comInt = floor ( count ( $intAmount ) / 2 ); // 整数位逗号的个数
        for($i = 0; $i < $comInt; $i ++) {
            $intAmount [2 * $i + 1] = $this->num_company [$i%8];//在每个数后面插入相应的单位
        }
        // 将数组按照键名降序排序,即先将数组$intAmount中的值反转了一下,解决了strrev翻转中文字符串会出现乱码的问题
        krsort ( $intAmount ); // 将数组按照键名降序排序
        $intStr = implode ( '', $intAmount );
        // $intStr=strrev($intStr);//翻转中文字符串会出现乱码,因此采用上面的方法
        $intStr=$intStr.$this->RMBunit[0];//给整数段加上人民币单位元
        return $intStr;//返回加入了单位的整数段
    }
    public function  getchinese(){
        $amount=$this->amount;
        $num = array ();
        $num = explode ( '.', $amount ); // 将金额的整数位和小数位分开
        $cN = count ( $num );//$cN为1指没有小数,为2则有小数
        $k=$this->checkisfloat($cN, $num);//检查是否有小数位
        $numtoChinese=$this->num2chinese($num, $cN, $k);//所有数字转换成汉字
        $decStr=$this->dec2chinese($numtoChinese, $cN, $k);//小数段汉字化完成
        $intStr=$this->int2chinese($numtoChinese);//汉化的整数位,还有待进一步处理

        $intStr=str_replace('零圆', '圆', $intStr);//如果个位为零,则将其替换删除
        $intStr=str_replace('零万', '万零万', $intStr);//如果万位为零,则删除
        $intStr=str_replace('零亿', '亿零亿', $intStr);//如果亿位为零,则删除
        /* 下面是将所有的连续的位数为零删除只留一个零 */
        $pattern = '/(零[\x{4e00}-\x{9fa5}])+/iu'; // /[\x{4e00}-\x{9fa5}]/iu 匹配汉字,/[^\x{4e00}-\x{9fa5}]/iu 匹配非汉字
        $replacement = '零';
        $intStr = preg_replace ( $pattern, $replacement, $intStr );//将多余的零替换掉
        /* 合并汉化完成的金额 */
        if ($cN>1){
            $amountStr=$intStr.$decStr;
        }else{
            $amountStr=$intStr;
        }
        return $amountStr;
    }
}

/* 测试 */
$amount = "10250082.567";
$turn=new money2chinese($amount);
$res=$turn->getchinese();
echo '小写金额: '.$amount."\t  大写金额: ".$res;
var_dump($res);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值