Javascript PHP中的NumberFormat与JS中的NumberFormat

Javascript PHP中的NumberFormat与JS中的NumberFormat,javascript,php,internationalization,Javascript,Php,Internationalization,在尝试格式化货币时,我似乎得到了非常不一致的结果。在PHP中,我使用的是。我有以下演示代码: $number = 5125.99; echo getInternationallyFormattedCurrency($number, 'tl-PH', 'PHP'); echo '<br/>'; echo getInternationallyFormattedCurrency($number, 'fil-PH', 'PHP'); echo '<br/>'; echo getI

在尝试格式化货币时,我似乎得到了非常不一致的结果。在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.12-ICU版本4.2.1)时,我得到以下结果:

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

$5,125.99
$5,125.99
$5,125.99
₱ 5125.99
₱ 5125.99
₱5,125.99

$ 5125.99
$ 5125.99
$5,125.99
> "PHP 5,125.99"
> "₱5,125.99"
> "PHP 5,125.99"
> "$5,125.99"
> "$5,125.99"
> "$5,125.99"
为什么会有区别?哪一个是正确的?我猜我的本地机器是因为ICU版本更高?

我也需要JS提供完全相同的功能。因此,在上面,我放置了以下等效代码:

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));
我明白了:

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

$5,125.99
$5,125.99
$5,125.99
₱ 5125.99
₱ 5125.99
₱5,125.99

$ 5125.99
$ 5125.99
$5,125.99
> "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版本有一些提示,但显然不建议这样做

更新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);
    }
}
因此,为了100%安全,我建议为格式化目的创建一个小型服务器端组件,这样您就可以传递区域设置、值和货币,并且无论是后端还是前端需要格式化字符串,结果总是相同的


另外,请注意,
tl PH
tl_PH
是不同的。始终使用
tl\u PH
fil\u PH
en\u US

只是一个想法。。。但是为了在两种不同的语言中获得一致的结果,我建议使用完全相同的库代码

如果您曾经在PHP端运行Intl.NumberFormat会怎么样?这里还有一个例子


我可能会使用这条路径从php端获得所有一致性,因为php依赖于底层C库,这就是不一致性的来源(在编译时):

关于不同格式的注释实际上并不取决于 PHP版本,但在icu库的版本上,PHP是 已根据编译,因为此库的数据库具有格式设置 不同地区的规则。

php没什么可做的,我们必须格外小心

下面是自己测试后的一些注意事项

这些代码段返回格式化的数字(不会返回科学记数法),但是是四舍五入的,这是不需要的。它负责数千人,我们可以选择显示或不显示。在我看来,这是个坏主意,我想避开它们

javascript,有:

var编号=5125.956665433245556679;
console.log(“\n”,
number.toLocaleString('fil-PH',{maximumFractionDigits:5,样式:'currency',货币:'PHP',useGrouping:true})
,“\n”,
number.toLocaleString('fil-PH',{maximumFractionDigits:5,样式:'currency',货币:'PHP',useGrouping:false})
,“\n”,
number.toLocaleString('fullwide',{maximumFractionDigits:5,样式:'currency',币种:'USD',useGrouping:true})
,“\n”,
number.toLocaleString('fullwide',{maximumFractionDigits:5,样式:'currency',币种:'USD',currencyDisplay:'symbol',useGrouping:false})

)
两个PHP版本是否相同?(Localhost&Server)更新了我的帖子以指示版本。Localhost是7.3.7;服务器是7.3.12。您是否检查了每个PHP+intl扩展的ICU版本?我不知道你的代码和我的有什么不同?我使用了OOP方法,而您使用的是过程式风格。这并没有解决我从PHP和JS中获得的输出的差异(这很可能是由ICU版本差异引起的)。您的“服务器端组件”想法本质上是我的更新3吗?我想您应该注意我的最后一条评论-在上面的代码中,您使用了错误的本地化标识符,这可能解释了代码中的奇怪行为。同样,tl PH与tl_PH不同。尝试将所有设置为“tl_PH”、“fil_PH”和“en_US”,您的问题可能会消失。这将是重新发明轮子。格式化数字要比这复杂得多(例如,千位分隔符、小数点、小数位数等)。所有这些选项都可以在两个api中指定。这不是重新发明轮子,这是经过严格测试和生产的!我指定了如何显示或不显示
1000个分隔符
,并显示了在两种语言中指定的
小数点
处剪切的正确方式。