javascript - PHP 中的 NumberFormatter 与 JS 中的 NumberFormat

标签 javascript php internationalization

尝试格式化货币时,我似乎得到了非常不一致的结果。在 PHP 中,我使用 https://www.php.net/manual/en/class.numberformatter.php .我有以下演示代码:

$number = 5125.99;
echo getInternationallyFormattedCurrency($number, 'tl-PH', 'PHP');
echo '<br/>';
echo getInternationallyFormattedCurrency($number, 'fil-PH', 'PHP');
echo '<br/>';
echo getInternationallyFormattedCurrency($number, 'en-US', 'PHP');
echo '<br/>';
echo '<br/>';
echo getInternationallyFormattedCurrency($number, 'tl_PH', 'USD');
echo '<br/>';
echo getInternationallyFormattedCurrency($number, 'fil_PH', 'USD');
echo '<br/>';
echo getInternationallyFormattedCurrency($number, 'en_US', 'USD');
echo '<br/>';

当我在我的本地主机上运行它时(是 PHP 版本 7.3.7,但我更新以匹配我的服务器的 PHP 版本 7.3.12 - ICU 版本 64.2),我得到这个:
₱5,125.99
₱5,125.99
PHP 5,125.99

$5,125.99
$5,125.99
$5,125.99

但是,当我在我的服务器上运行它时(PHP 版本 7.3.12 - ICU 版本 4.2.1),我得到了这个:
₱ 5125.99
₱ 5125.99
₱5,125.99

$ 5125.99
$ 5125.99
$5,125.99

为什么有区别?哪一个实际上是正确的?由于 ICU 版本较高,我猜我的本地机器?

我也需要来自 JS 的完全相同的功能。所以,在 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat ,我把下面的等效代码:
var number = 5125.99;

console.log(new Intl.NumberFormat('tl-PH', { style: 'currency', currency: 'PHP' }).format(number));
console.log(new Intl.NumberFormat('fil-PH', { style: 'currency', currency: 'PHP' }).format(number));
console.log(new Intl.NumberFormat('en-US', { style: 'currency', currency: 'PHP' }).format(number));
console.log(new Intl.NumberFormat('tl-PH', { style: 'currency', currency: 'USD' }).format(number));
console.log(new Intl.NumberFormat('fil-PH', { style: 'currency', currency: 'USD' }).format(number));
console.log(new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(number));

我明白了:
> "PHP 5,125.99"
> "₱5,125.99"
> "PHP 5,125.99"
> "$5,125.99"
> "$5,125.99"
> "$5,125.99"

所以 - 这是另一个结果。 我需要一种方法来格式化 PHP 和 JS 之间的货币一致性。我该怎么做呢?

更新 1:

我的本地机器的 ICU 版本是 64.2,而我的服务器是 4.2.1。我会看看我的托管服务提供商是否可以将 ICU 版本更新到最新版本。这可能解释了我的本地机器输出与我的服务器输出之间的差异。

仍然不确定为什么 JS 的行为不同。

更新 2:

我的托管公司说因为 cPanel,我需要坚持使用 ICU 版本 4.2.1。虽然 cPanel 有一些关于如何升级 ICU 版本的提示,但显然不建议这样做。
  • https://forums.cpanel.net/threads/internationalization-extension-version-upgrade.612607/
  • https://forums.cpanel.net/threads/install-php71-php-intl-with-a-more-recent-version-of-icu.620979/

  • 更新 3:

    我现在正在考虑让我的 JS 对将处理数字格式的 PHP 方法进行 Ajax 调用,这样我可以确定我得到了相同的格式输出。不过,感觉像是一个缓慢而昂贵的解决方案。

    最佳答案

    我尝试了这种方法:

    <?php
    
    function process($locale, $value, $currency){
        $fmt = numfmt_create($locale, NumberFormatter::CURRENCY );
        echo "Locale: $locale, Currency: $currency, Result: " . $fmt->formatCurrency($value, $currency) . "\n";
    }
    
    $locales = ["tl_PH","fil_PH", "en_US"];
    $currencies = ["USD", "PHP"];
    $value = 5125.99;
    
    foreach ($locales as $locale){
        foreach ($currencies as $currency){
            process($locale, $value, $currency);
        }
    }
    

    并得到一致的结果:
    Locale: tl_PH, Currency: USD, Result: $5,125.99
    Locale: tl_PH, Currency: PHP, Result: ₱5,125.99
    Locale: fil_PH, Currency: USD, Result: $5,125.99
    Locale: fil_PH, Currency: PHP, Result: ₱5,125.99
    Locale: en_US, Currency: USD, Result: $5,125.99
    Locale: en_US, Currency: PHP, Result: PHP 5,125.99
    

    因此,为了 100% 安全,我建议为格式化目的创建一个小型服务器端组件,这样您就可以传递语言环境、值和货币,并且无论是后端还是前端需要格式化字符串,都始终得到相同的结果.

    另外,请注意 tl-PHtl_PH不一样。使用tl_PHfil_PHen_US始终如一。

    关于javascript - PHP 中的 NumberFormatter 与 JS 中的 NumberFormat,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59242134/

    相关文章:

    php - 我正在尝试通过串行端口与微 Controller 进行通信。但我的 php 脚本给了我一个错误

    c# - 使用 JavaScript 检索文本框

    javascript - angularjs:如何获取与在文本区域中输入完全相同的文本,包括换行?

    php - Javascript calc 函数运行两次的问题

    php - 序列化失败: Deadlock found when trying to get lock

    c - dcgettext 的目的是什么?

    php - CakePHP JavaScript 文件中的国际化

    javascript - 提交跨域ajax POST请求

    javascript - 为什么谷歌环聊在最新的 Chrome 中支持共享桌面而没有 Chrome 扩展?

    ios - 基本 Storyboard仅考虑多语言应用程序中的 LTR 界面