php金额转中文大写

/**
     * 金额转中文大写
     * @param mixed $amount 待转换金额
     * @param bool $financeMode 是否启用财务模式(true:仅保留角分+四舍五入;false:支持厘/毫)
     * @return string 大写金额
     */
    public static function amountConvertCapital($amount, bool $financeMode = true): string
    {
        // 1. 输入校验与格式化:仅保留数字、小数点、负号
        $amount = preg_replace('/[^0-9.\-]/', '', (string)$amount);
        if ($amount === '' || $amount === '-') {
            return '人民币零圆整';
        }

        // 标记负数并去除负号
        $isNegative = strpos($amount, '-') === 0;
        $amount = ltrim($amount, '-');
        $amount = floatval($amount);

        // 2. 小数位处理:财务模式保留2位(角分),非财务保留4位(厘毫)
        $decimalLen = $financeMode ? 2 : 4;
        $amount = round($amount, $decimalLen);
        $numStr = sprintf("%.{$decimalLen}f", $amount);
        list($intPart, $decPart) = explode('.', $numStr);

        // 清理前导/末尾零
        $intPart = ltrim($intPart, '0');
        $decPart = rtrim($decPart, '0');

        // 3. 定义基础配置
        $capitalNumbers = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
        $integerUnits = ['', '拾', '佰', '仟'];
        $placeUnits = ['', '万', '亿', '兆'];
        $decimalUnits = ['角', '分', '厘', '毫'];
        $result = [];

        // 4. 转换整数部分(修复10/1005等特殊数字)
        if ($intPart !== '') {
            $integerNumbers = array_reverse(str_split($intPart));
            $lastIsZero = false;
            foreach (array_chunk($integerNumbers, 4) as $chunkKey => $chunk) {
                $chunkStr = '';
                foreach ($chunk as $key => $number) {
                    $number = (int)$number;
                    if ($number === 0) {
                        if (!$lastIsZero) {
                            $chunkStr .= $capitalNumbers[0];
                            $lastIsZero = true;
                        }
                    } else {
                        $chunkStr .= $capitalNumbers[$number] . $integerUnits[$key];
                        $lastIsZero = false;
                    }
                }
                // 清理chunk末尾零,添加万/亿/兆单位
                $chunkStr = rtrim($chunkStr, $capitalNumbers[0]);
                if ($chunkStr !== '') {
                    array_unshift($result, $chunkStr . $placeUnits[$chunkKey]);
                }
            }
            // 修复拾位开头(如10 → 壹拾,而非拾)
            $resultStr = implode('', $result);
            $resultStr = preg_replace('/^拾/', '壹拾', $resultStr);
            $result = [$resultStr];
        } else {
            array_push($result, $capitalNumbers[0]); // 整数部分为0
        }
        array_push($result, '圆');

        // 5. 转换小数部分
        if ($decPart !== '') {
            $decimalNumbers = str_split($decPart);
            foreach ($decimalNumbers as $key => $number) {
                array_push($result, $capitalNumbers[$number]);
                array_push($result, $decimalUnits[$key]);
            }
            // 财务模式:有角无分补“整”
            if ($financeMode && strlen($decPart) === 1) {
                array_push($result, '整');
            }
        } else {
            array_push($result, '整'); // 无小数位加“整”
        }

        // 6. 处理负数
        if ($isNegative) {
            array_unshift($result, '负');
        }

        // 7. 清理冗余零,拼接最终结果
        $final = '人民币' . implode('', $result);
        $final = preg_replace('/零+/', '零', $final);
        $final = preg_replace('/零圆/', '圆', $final);

        return $final;
    }
posted @ 2026-02-07 10:37  pine007  阅读(2)  评论(0)    收藏  举报