php实现数字转中文大写金额表示

通义里给出的回答,但在实践中发现问题,只要第1个数字是6,那转换出来结果就是乱码。

<?php

function numberToChinese($num) {
    // 判断是否是数字
    if (!is_numeric($num)) {
        return '请输入数字';
    }

    // 数字转字符串并处理小数点
    $num = sprintf('%.2f', $num);  // 保留两位小数
    list($integer, $decimal) = explode('.', $num);

    // 定义映射关系
    $digits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
    $units = ['', '拾', '佰', '仟'];
    $bigUnits = ['', '万', '亿', '万亿'];

    // 处理整数部分
    $integerStr = '';
    $length = strlen($integer);
    $zeroFlag = false;

    for ($i = 0; $i < $length; $i++) {
        $pos = $length - $i - 1;
        $digit = (int)$integer[$i];
        $unit = $pos % 4;
        $bigUnit = floor($pos / 4);

        if ($digit === 0) {
            if (!$zeroFlag && ($integerStr !== '')) {
                $integerStr .= $digits[0];
                $zeroFlag = true;
            }
        } else {
            $zeroFlag = false;
            $integerStr .= $digits[$digit] . $units[$unit];

            // 添加“万”、“亿”等单位
            if ($unit === 0 && $bigUnits[$bigUnit] !== '') {
                $integerStr .= $bigUnits[$bigUnit];
            }
        }
    }

    // 去除多余的零
    $integerStr = str_replace($digits[0] . $digits[0], $digits[0], $integerStr);
    $integerStr = trim($integerStr, $digits[0]);

    // 处理小数部分
    $decimalStr = '';
    if ((int)$decimal > 0) {
        $jiao = (int)substr($decimal, 0, 1);
        $fen = (int)substr($decimal, 1, 1);
        if ($jiao > 0) {
            $decimalStr .= $digits[$jiao] . '角';
        }
        if ($fen > 0) {
            $decimalStr .= $digits[$fen] . '分';
        }
    } else {
        $decimalStr = '整';
    }

    // 拼接结果
    return $integerStr . '元' . $decimalStr;
}

// 示例用法
$amount = 12345.67;
echo numberToChinese($amount);  // 输出:壹万贰仟叁佰肆拾伍元陆角柒分

问题代码在于第47行的$integerStr = trim($integerStr, $digits[0]);
如果 $integerStr : 陆,$digits[0]:零零。返回的结果就是乱码。

修复代码:

$integerStr = preg_replace("/{$digits[0]}+$/", '', $integerStr);
$integerStr = preg_replace("/^{$digits[0]}+/", '', $integerStr);

最终完整代码

/**
 * @param float $num
 * @return string
 */
public function numberToChinese($num) {
    // 判断是否是数字
    if (!is_numeric($num)) {
        return '请输入数字';
    }

    // 数字转字符串并处理小数点
    $num = sprintf('%.2f', $num);  // 保留两位小数
    list($integer, $decimal) = explode('.', $num);

    // 定义映射关系
    $digits = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
    $units = ['', '拾', '佰', '仟'];
    $bigUnits = ['', '万', '亿', '万亿'];

    // 处理整数部分
    $integerStr = '';
    $length = strlen($integer);
    $zeroFlag = false;

    for ($i = 0; $i < $length; $i++) {
        $pos = $length - $i - 1;
        $digit = (int)$integer[$i];
        $unit = $pos % 4;
        $bigUnit = floor($pos / 4);

        if ($digit === 0) {
            if (!$zeroFlag && ($integerStr !== '')) {
                $integerStr .= $digits[0];
                $zeroFlag = true;
            }
        } else {
            $zeroFlag = false;
            $integerStr .= $digits[$digit] . $units[$unit];

            // 添加“万”、“亿”等单位
            if ($unit === 0 && $bigUnits[$bigUnit] !== '') {
                $integerStr .= $bigUnits[$bigUnit];
            }
        }
    }

    // 去除多余的零
    $integerStr = str_replace($digits[0] . $digits[0], $digits[0], $integerStr);
    // $integerStr:陆 $digits[0]:零零
    // $integerStr = trim($integerStr, $digits[0]);
    $integerStr = preg_replace("/{$digits[0]}+$/", '', $integerStr);
    $integerStr = preg_replace("/^{$digits[0]}+/", '', $integerStr);

    // 处理小数部分
    $decimalStr = '';
    if ((int)$decimal > 0) {
        $jiao = (int)substr($decimal, 0, 1);
        $fen = (int)substr($decimal, 1, 1);
        if ($jiao > 0) {
            $decimalStr .= $digits[$jiao] . '角';
        }
        if ($fen > 0) {
            $decimalStr .= $digits[$fen] . '分';
        }
    } else {
        $decimalStr = '整';
    }

    // 拼接结果
    return $integerStr . '元' . $decimalStr;
}

 

posted @ 2025-06-24 17:36  imzhi  阅读(42)  评论(0)    收藏  举报