PHP 实现金额数字转英文文本函数
在涉及财务报表或国际业务的 PHP 开发中,常需将数字金额转换为规范的英文大写文本(如 "ONE HUNDRED DOLLARS ONLY")。本文将演示如何编写两个核心函数 fmoney 和 umoney,前者负责千分位格式化,后者负责逻辑拆解与词汇拼接,支持美元(USD)和人民币(RMB)的双币种输出。
核心功能与结果
该方案主要解决两个问题:
- 数字格式化:将浮点数统一为两位小数并进行千分位分隔,例如
1220.01变为1,220.01。 - 文本转换:将格式化后的数字按层级(百、千、万等)映射为英文单词,并添加货币后缀(如 "DOLLARS", "CENTS ONLY")。
调用示例如下:
- echo fmoney(1220.01); 输出: 1,220.01
- echo umoney(1220.01); 输出: ONE THOUSAND AND TWO HUNDRED TWENTY DOLLARS AND TWENTY-ONE CENTS ONLY
- echo umoney(1220.01, 'rmb'); 输出: ONE THOUSAND AND TWO HUNDRED TWENTY YUAN AND TWENTY-ONE FEN ONLY
准备条件
无需安装额外扩展。代码依赖于 PHP 基础字符串操作函数(如 sprintf, explode, substr)和全局数组管理。由于金额转换涉及复杂的层级对应关系(个、十、百、千、百万等),建议将数字到英文的映射表定义为全局变量或常量,以便复用和维护。
真实操作顺序
第1步:定义数字与单位映射表
为了准确翻译,首先需要建立从数字到英文单词的查找表。这包括 0-20 的基础数字、30-90 的整十数以及 HUNDRED, THOUSAND, MILLION 等量级词。
同时定义货币类型标识,如 usd 对应 DOLLARS / CENTS ONLY,rmb 对应 YUAN / FEN ONLY。
global $numTable, $commaTable, $moneyType;
$numTable = array(
0=>"ZERO ", 1=>"ONE ", 2=>"TWO ", 3=>"THREE ", 4=>"FOUR ",
5=>"FIVE ", 6=>"SIX ", 7=>"SEVEN ", 8=>"EIGHT ", 9=>"NINE ",
10=>"TEN ", 11=>"ELEVEN ", 12=>"TWELVE ", 13=>"THIRTEEN ",
14=>"FOURTEEN ", 15=>"FIFTEEN ", 16=>"SIXTEEN ", 17=>"SEVENTEEN ",
18=>"EIGHTEEN ", 19=>"NINETEEN ", 20=>"TWENTY ",
30=>"THIRTY ", 40=>"FORTY ", 50=>"FIFTY ", 60=>"SIXTY ",
70=>"SEVENTY ", 80=>"EIGHTY ", 90=>"NINETY "
);
$commaTable = array(
0=>"HUNDRED ", 1=>"THOUSAND ", 2=>"MILLION ",
3=>"MILLIARD ", 4=>"BILLION "
);
$moneyType["usd"] = "DOLLARS ";
$moneyType["usd_1"] = "CENTS ONLY";
$moneyType["rmb"] = "YUAN ";
$moneyType["rmb_1"] = "FEN ONLY";
第2步:实现金额千分位格式化函数 fmoney
此函数接收一个数字,确保其保留两位小数,并从右向左每三位插入一个逗号。它返回格式化后的字符串,供后续拆分使用。
function fmoney($num) {
$num = 0 + $num; // 确保为数值型
$num = sprintf("%.02f", $num); // 固定两位小数
if (strlen($num) <= 6) return $num; // 较短数字直接返回
$k = 1; $j = 100; // j用作数组索引反向计数
for ($i = strlen($num) - 1; $i >= 0; $i--, $k++) {
$one_num = substr($num, $i, 1);
if ($one_num == ".") {
$numArray[$j--] = $one_num;
$k = 0; continue;
}
// 每3位加逗号,但最后部分不加
if ($k % 3 == 0 && $i != 0) {
$numArray[$j--] = $one_num;
$numArray[$j--] = ",";
$k = 0;
} else {
$numArray[$j--] = $one_num;
}
}
ksort($numArray); // 重新排序索引
return join("", $numArray);
}
第3步:实现主转换函数 umoney
umoney 是核心逻辑入口。它先调用 fmoney 获取格式化串,然后以逗号为界拆分数组。遍历每个分段(代表不同的量级,如千位段、百万位段),逐段调用内部辅助函数 format3num 转化为英文,并根据当前位置追加对应的量级词(THOUSAND, MILLION)及货币后缀。
function umoney($num, $type = "usd") {
global $numTable, $commaTable, $moneyType;
if ($type == "") $type = "usd";
$fnum = fmoney($num);
$numArray = explode(",", $fnum);
$resultArray = array();
$k = 0;
$cc = count($numArray);
for ($i = 0; $i < count($numArray); $i++) {
$num_str = $numArray[$i];
if (eregi("\.", $num_str)) {
// 处理小数位(cents/fen)
$dotArray = explode(".", $num_str);
if ($dotArray[1] != 0) {
$resultArray[$k++] = format3num($dotArray[0] + 0);
$resultArray[$k++] = $moneyType[strtolower($type)];
$resultArray[$k++] = "AND ";
$resultArray[$k++] = format3num($dotArray[1] + 0);
$resultArray[$k++] = $moneyType[strtolower($type)."_1"];
} else {
$resultArray[$k++] = format3num($dotArray[0] + 0);
$resultArray[$k++] = $moneyType[strtolower($type)];
}
} else {
// 处理整数位
if (($num_str + 0) != 0) {
$resultArray[$k++] = format3num($num_str + 0);
$resultArray[$k++] = $commaTable[--$cc]; // 添加量级词
// 检查是否需要在不同层级间添加 "AND"
for ($j = $i; $j <= $cc; $j++) {
if ($numArray[$j] != 0) {
$resultArray[$k++] = "AND ";
break;
}
}
}
}
}
return join("", $resultArray);
}
第4步:实现单段数字转换辅助函数 format3num
此函数专门处理 0-999 范围内的数字转换逻辑,区分三位数(含百位)、两位数(含十位)和一位数的情况,并处理特殊情况如 11-19 的特殊拼写。
function format3num($num) {
global $numTable, $commaTable;
$numlen = strlen($num);
for ($i = 0, $j = 0; $i < $numlen; $i++) {
$bitenum[$j++] = substr($num, $i, 1);
}
if ($num == 0) return "";
if ($numlen == 1) {
return $numTable[$num];
}
if ($numlen == 2) {
if ($num <= 20) return $numTable[$num];
if ($bitenum[1] == 0) { // 如 20, 30
return $numTable[$num];
} else {
return trim($numTable[$bitenum[0]*10]) . "-" . $numTable[$bitenum[1]]; // 如 21-TWENTY-ONE
}
}
// 三位数处理 (100-999)
if ($numlen == 3) {
if ($bitenum[1] == 0 && $bitenum[2] == 0) {
return $numTable[$bitenum[0]] . $commaTable[0]; // 100 -> ONE HUNDRED
} elseif ($bitenum[1] == 0) {
return $numTable[$bitenum[0]] . $commaTable[0] . $numTable[$bitenum[2]]; // 102 -> ONE HUNDRED TWO
} elseif ($bitenum[2] == 0) {
return $numTable[$bitenum[0]] . $commaTable[0] . $numTable[$bitenum[1]*10]; // 120 -> ONE HUNDRED TWENTY
} else {
return $numTable[$bitenum[0]] . $commaTable[0] . trim($numTable[$bitenum[1]*10]) . "-" . $numTable[$bitenum[2]]; // 123
}
}
return $num;
}
完成判断
当代码运行后,输入任意正浮点数并调用 umoney,若控制台或浏览器正确输出了包含量级词、货币名称及 "AND" 连接的标准英文大写句子,则转换成功。注意,本实现主要面向正数,对于负数或极大数值(超过万亿),可能需要扩展 $commaTable 中的量级词。
简要总结
通过组合 fmoney 的格式化能力与 umoney 的分层解析逻辑,我们可以高效地在 PHP 环境中实现金额的英文化。关键在于维护好基础的数字映射表($numTable)以及正确处理层级间的 “AND” 连接规则。以上就是PHP 金额数字转换成英文的详细内容,更多关于 PHP 财务工具开发的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









