金額從數字轉換成中文漢字大寫的實現
阿新 • • 發佈:2019-01-02
以下簡單封裝的實現方法,詳細見註釋
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);