我正在尝试将本地化的货币字符串解析为货币和浮点值。
一段时间以来一切正常,现在我们遇到了一些问题。 NumberFormatter::parseCurrency 似乎使用了一个额外的不可见字符:
测试代码:
<?php
$formatter = new NumberFormatter("de_DE", NumberFormatter::CURRENCY);
var_dump(array(
$formatter->parseCurrency("88,22 €", $curr), // taken from output of $formatter->format(88.22)
$formatter->parseCurrency("88,22 €", $curr), // input with keyboard
$formatter->parseCurrency("88,22 \xE2\x82\xAc", $curr), // just a test
$formatter->format(88.22),
"88,22 €" // keyboard input
));
输出:
array(5) {
[0]=> float(88,22)
[1]=> bool(false)
[2]=> bool(false)
[3]=> string(10) "88,22 €" // this as input works
[4]=> string(9) "88,22 €" // this not...
}
如您所见,输出 3 和 4 的字符串长度有所不同。
我在 PHP 5.3(启用了 mbstring 的 ubuntu)和 5.4(Mac OS X 上的 Zend Server)中得到了相同的结果。
主要问题是,来 self 的表单(ZF1 应用程序)的输入值与索引 4 的输出相同...
有什么建议吗?提前致谢
编辑1:
工作值的hexdump:
00000000 38 38 2c 32 32 c2 a0 e2 82 ac 0a |88,22......|
0000000b
非工作值的 hexdump:
00000000 38 38 2c 32 32 20 e2 82 ac 0a |88,22 ....|
0000000a
编辑2:
好像是used whitepsace的问题。 c2 a0 是 NO-BREAK SPACE 并且(也许?)NumberFormatter::parseCurrency() 需要。但 0x20 是默认空间(在输入表单中输入)。
当前的解决方法是用 $value = str_replace("\x20", "\xC2\xA0", $value);
编辑3:
在另一个系统上(带有 Zend Server 5.6 的 Mac OS X,启用了 mbstring,PHP 5.3.14)一切都按预期工作:
array(5) {
[0]=> float(88,22)
[1]=> float(88,22)
[2]=> float(88,22)
[3]=> string(9) "88,22 €"
[4]=> string(9) "88,22 €"
}
编辑4:
使用空格和使用非中断空间配置的主要区别在于 ICU 版本:
工作版本:
intl
Internationalization support => enabled
version => 1.1.0
ICU version => 3.8.1
Directive => Local Value => Master Value
intl.default_locale => no value => no value
intl.error_level => 0 => 0
无效版本:
intl
Internationalization support => enabled
version => 1.1.0
ICU version => 4.8.1.1
ICU Data version => 4.8.1
Directive => Local Value => Master Value
intl.default_locale => no value => no value
intl.error_level => 0 => 0
最佳答案
NumberFormatter::parseCurrency
是 ICU 库函数的薄包装器 unum_parseDoubleCurrency
(see source)。
ICU 库函数是有限制的,因为它只会解析由其双重函数 unum_formatDoubleCurrency
产生的字符串。 .该格式由 Unicode 区域设置数据驱动,它指定货币值和数值之间的不间断空格。显然,早期版本的库接受了其他空白字符。
简而言之,你做不到NumberFormatter::parseCurrency
接受空格。然而,Zend_Currency
默认情况下还应该输出不间断空格:
$currency = new Zend_Currency(array(
'currency' => 'EUR',
'value' => 88.22,
), 'de_DE');
var_dump(
strval($currency), // 88,22 €
strpos($currency, "\x20"), // false
strpos($currency, "\xc2\xa0") // 5
);
问题是您的应用程序的哪一部分正在输出空格以及您如何处理它。你提到它是你表单的一部分,所以也许你可以看看让表单将货币和值作为单独的字段返回,这样你就不必担心解析数字。如果用户自己输入字符串“88,22 €”,您可能会遇到比空格问题更多的问题。话虽如此,如果您想使用 \x20
,您提到的解决方法(将 \xc2\xa0
替换为 NumberFormatter
)是解决该问题的唯一方法。 .
关于php - 如何更改 NumberFormatter::parseCurrency() 接受空格和不间断空格的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16438229/