开发者社区 问答 正文

PHP中的NumberFormatter与JS中的NumberFormat

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

$number = 5125.99; echo getInternationallyFormattedCurrency($number, 'tl-PH', 'PHP'); echo '
'; echo getInternationallyFormattedCurrency($number, 'fil-PH', 'PHP'); echo '
'; echo getInternationallyFormattedCurrency($number, 'en-US', 'PHP'); echo '
'; echo '
'; echo getInternationallyFormattedCurrency($number, 'tl_PH', 'USD'); echo '
'; echo getInternationallyFormattedCurrency($number, 'fil_PH', 'USD'); echo '
'; echo getInternationallyFormattedCurrency($number, 'en_US', 'USD'); echo '
'; 当我在本地主机上运行此版本(版本为PHP 7.3.7,但已更新为与服务器的PHP版本7.3.12匹配)时,我得到了:

₱5,125.99 ₱5,125.99 PHP 5,125.99

$5,125.99 $5,125.99 $5,125.99 但是,当我在服务器(PHP版本7.3.12)上运行它时,会得到以下信息:

₱ 5125.99 ₱ 5125.99 ₱5,125.99

$ 5125.99 $ 5125.99 $5,125.99 为什么会有所不同?哪个实际上是正确的?

我也需要JS完全相同的功能。因此,在https://developer.mozilla.org/zh-CN/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,而服务器的ICU版本为4.2.1。我将查看托管服务提供商是否可以将ICU版本更新为最新版本。这可能可以解释本地计算机输出与服务器输出之间的差异。

仍然不确定为什么JS表现不同。

展开
收起
社区秘书 2019-12-09 16:50:11 654 分享 版权
阿里云 AI 助理回答

在处理货币格式化时,出现不一致的结果通常与几个因素相关:环境配置(如ICU版本,你已经提到)、语言标签的书写方式、以及运行环境的具体实现。下面是一些建议来帮助你解决这个问题:

1. 统一ICU版本

正如你所发现的,ICU(International Components for Unicode)库的不同版本可能导致格式化结果的差异。ICU是许多编程语言和平台用于国际化和本地化的库,包括PHP和JavaScript引擎。如果可能,确保所有环境中使用的是相同或相近版本的ICU,这将有助于减少因库差异导致的格式化不一致。

2. 标准化语言标签

在你的示例中,你使用了不同风格的语言标签,比如'tl-PH'、'fil-PH'以及'en-US',同时还有'tl_PH'和'fil_PH'这样的变体。虽然很多情况下现代库能够正确解析这些变化,但最好遵循标准的BCP47语言标签规范,即使用短横线(-)分隔区域和语言代码,例如'tl-PH'、'fil-PH'和'en-US'。统一这种方式可以减少因标签格式不一致带来的问题。

3. 使用稳定的API和库

对于PHP,确保使用NumberFormatter类时遵循最佳实践,并且检查是否有已知的bug或更新影响到你的版本。有时候,升级到一个更稳定的小版本或者应用补丁可以解决问题。

4. 在JavaScript中保持一致性

对于JavaScript,你已经在使用Intl.NumberFormat,这是一个很好的选择,因为它基于ECMAScript国际ization API,旨在提供跨环境的一致性。尽管如此,浏览器和JavaScript运行时(如Node.js)的实现可能会有细微差别,尤其是它们依赖的ICU版本不同。如果你的应用需要在多种环境下运行,考虑使用polyfill或shim来确保所有环境都有一致的支持,例如intl库。

5. 自定义格式化逻辑

作为最后的手段,如果上述方法都不能满足需求,你可以编写自定义的格式化逻辑来确保完全控制输出格式。但这通常是不得已而为之,因为维护成本较高且可能牺牲一些国际化特性。

结论

首先尝试通过更新ICU版本和标准化语言标签来解决服务器端的问题。对于客户端JavaScript,由于大多数现代浏览器对Intl.NumberFormat支持良好,差异可能较小,但仍建议测试目标用户群体使用的主流浏览器以确认一致性。如果仍然存在差异,考虑采用polyfill来增强兼容性。您也可以通过ECS一键诊断全面排查并修复ECS问题。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答