首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 實現千分位分隔符格式化:金融級數字字符串處理

     編輯:PHP 相關知識

從手寫算法到 number_format:大數字可讀性格式化的最佳實踐

在金融、電商、報表系統中,將 1234567890 格式化為 1,234,567,890 是基礎需求。本文對比手寫逆序分組算法與內置 number_format()、NumberFormatter 的優劣,給出多場景選型建議。

手寫算法教學版(理解原理)

<?php
/**
 * 手寫實現:每 3 位插入逗號(僅供演示,生產請用內置函數)
 */
function splitStrWithComma(string $str): string
{
    if (!ctype_digit($str)) {
        throw new InvalidArgumentException('輸入必須為純數字字符串');
    }
    $len = strlen($str);
    $parts = [];
    for ($i = $len; $i > 0; $i -= 3) {
        $start = max(0, $i - 3);
        $parts[] = substr($str, $start, $i - $start);
    }
    return implode(',', array_reverse($parts));
}

echo splitStrWithComma('1234567890'); // 1,234,567,890

生產級方案對比

方案適用場景優點缺點/注意
number_format($num, 0, '.', ',')純整數、浮點數定點小數零依賴、極快、行為標準不支援區域化(如印度 1,00,000 格式)、超大整數超出 float 精度
NumberFormatter::create('zh_CN', NumberFormatter::DECIMAL)國際化、區域化格式、貨幣符號ICU 標準、支援所有 CLDR 格式需 intl 擴展、實例化開銷大、字符串輸入需先轉數值
sprintf('%0.0f', $num) + 正則極簡場景無額外函數依賴正則易錯、性能差、不推薦
手寫分組(本文教學版)教學、特殊分組邏輯(如 4 位分組)完全可控、支援任意長度字符串重複造輪子、易漏邊界、無小數/負號處理

實戰代碼片段

<?php
// 1. 簡單整數千分位
$price = 1234567890;
echo number_format($price, 0, '.', ','); // 1,234,567,890

// 2. 保留 2 位小數(金額標準)
$amount = 1234567.891;
echo number_format($amount, 2, '.', ','); // 1,234,567.89

// 3. 國際化:中文區域(萬/億單位)需自定義,NumberFormatter 不直接支援
// 推薦:自行實現中文數字格式化或用專用庫

// 4. 超大整數(超過 53 位精度)必須用字符串處理
$bigInt = '123456789012345678901234567890';
echo splitStrWithComma($bigInt); // 手寫函數支援任意長度

// 5. 貨幣格式化(帶符號、區域化)
$fmt = new NumberFormatter('zh_CN', NumberFormatter::CURRENCY);
echo $fmt->formatCurrency(12345.67, 'CNY'); // ¥12,345.67

避坑清單

  • float 精度陷阱:number_format(12345678901234567890, 0, '.', ',') 會科學計數法丟失精度,大整數務必用字符串或 BCMath/GMP。
  • 負數處理:手寫算法需單獨處理 - 符號,內置函數自動支援。
  • 小數位截斷 vs 四捨五入:number_format 是四捨五入,貨幣結算常需「銀行家算法」或截斷,請用 BCMath bcdiv 控制。
  • 前端同步:JS 端用 Intl.NumberFormat('zh-CN').format(num) 保持一致。

擴展:中文萬/億單位格式化

<?php
function formatChineseNumber(int|float|string $num): string
{
    $num = (string)$num;
    $sign = '';
    if ($num[0] === '-') { $sign = '-'; $num = substr($num, 1); }
    if (str_contains($num, '.')) { [$int, $dec] = explode('.', $num); } else { $int = $num; $dec = ''; }

    $len = strlen($int);
    if ($len <= 4) return $sign . $int . ($dec ? ".$dec" : '');
    if ($len <= 8) {
        $high = substr($int, 0, $len - 4);
        $low  = substr($int, -4);
        return $sign . $high . '萬' . ($low != '0000' ? $low : '') . ($dec ? ".$dec" : '');
    }
    $yi = substr($int, 0, $len - 8);
    $wan = substr($int, $len - 8, 4);
    $qian = substr($int, -4);
    return $sign . $yi . '億' . ($wan != '0000' ? $wan . '萬' : '') . ($qian != '0000' ? $qian : '') . ($dec ? ".$dec" : '');
}
echo formatChineseNumber(123456789); // 1億2345萬6789

選對工具、守住精度、考慮國際化,數字格式化才能經得起金融級業務的考驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved