开发者社区 问答 正文

PHP中的NumberFormatter与JS中的NumberFormat

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

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匹配)时,我得到了:

₱5,125.99
PHP 5,125.99

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

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

₱ 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:48:38 609 分享 版权
阿里云 AI 助理回答

不同环境(如本地主机与服务器)和不同编程语言(PHP与JavaScript)之间货币格式化结果的不一致,通常归因于几个因素:

  1. ICU库版本差异:您已经提到,您的本地计算机使用的是较新的ICU(国际组件 Unicode联盟)版本,而服务器上是较旧的版本。ICU库负责提供国际化和本地化的功能,包括日期、数字和货币的格式化。不同版本的ICU可能对某些地区的货币格式处理规则有不同的实现,导致了您观察到的差异。

  2. 语言标签标准化:在您的示例中,您使用了两种格式的语言标签(例如'tl-PH'与'tl_PH'),虽然很多情况下现代系统能够识别并正确处理这些差异,但最好遵循标准格式,比如使用'tl-PH'这样的BCP 47标准格式,以确保最大兼容性。

  3. PHP与JavaScript实现差异:尽管两者都试图遵循相同的国际化标准,但它们底层的实现细节、依赖的库(如PHP的NumberFormatter类与JavaScript的Intl.NumberFormat对象)以及这些库的具体版本,都可能导致细微的格式化差异。

为了在PHP和JavaScript之间保持货币格式的一致性,您可以采取以下措施:

  • 统一ICU版本:尽可能地在所有环境中使用相同版本的ICU库。这可能需要与您的服务器提供商沟通或自行编译更新ICU库,但这对于解决因库版本不同引起的问题至关重要。

  • 遵循标准化语言标签:确保在PHP和JavaScript中使用的语言和地区代码遵循相同的规范(通常是BCP 47标准),以减少因标签格式不一导致的差异。

  • 自定义格式化逻辑:如果直接使用内置函数无法达到完全一致的效果,可以考虑编写或采用第三方库来实现更精确的自定义格式化逻辑,确保跨平台一致性。例如,在两边都手动控制货币符号的位置、小数点后的位数等。

  • 测试和校准:在多个目标环境中进行充分的测试,根据测试结果微调格式化参数,直到达到期望的统一效果。

针对JavaScript部分,由于它依赖于浏览器或运行时环境(如Node.js)支持的Intl API,确保该环境也基于最新的ECMAScript国际化API标准,有助于提高格式化的一致性和准确性。

综上所述,通过升级和统一基础库版本、遵循标准、自定义必要逻辑,并进行全面测试,可以最大程度地减少跨PHP和JavaScript的货币格式化差异。您也可以通过ECS一键诊断全面排查并修复ECS问题。

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