Próbuję analizować zlokalizowane łańcuchy walut do waluty i wartości zmiennoprzecinkowej.Jak zmienić zachowanie NumberFormatter :: parseCurrency() dotyczące akceptowania białej przestrzeni i braku łamania przestrzeni?
Wszystko działa dobrze przez jakiś czas, teraz mamy pewne problemy. Wydaje się, że NumberFormatter :: parseCurrency wykorzystuje dodatkową niewidoczny znak:
Testcode:
<?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
));
wyjściowa:
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...
}
Jak widać, istnieje różnica w długości łańcucha produkcji 3 i 4.
Otrzymuję takie same wyniki w PHP 5.3 (ubuntu z włączonym mbstringiem) i 5.4 (serwer Zend na Mac OS X).
Głównym problemem jest to, wartości wejściowe z mojej postaci (ZF1 Application) są w równym stopniu do wyjścia z indeksem 4 ...
jakieś sugestie? z góry dzięki
Edit1:
hexdump wartości robocze:
00000000 38 38 2c 32 32 c2 a0 e2 82 ac 0a |88,22......|
0000000b
hexdump non wartości roboczej:
00000000 38 38 2c 32 32 20 e2 82 ac 0a |88,22 ....|
0000000a
Edit2:
Wydaje się, że jest to problem z używanym whitepsace. c2 a0 to NO-BREAK SPACE i (może?) wymagane przez NumberFormatter :: parseCurrency(). ale 0x20 jest domyślną przestrzenią (która jest wprowadzana w formularzu wejściowym). Obecny obejście jest zastąpienie spacje z NO-break przestrzeń z $value = str_replace("\x20", "\xC2\xA0", $value);
Edit3:
na innym systemie (Mac OS X z Zend Server 5.6, mbstring włączona, PHP 5.3.14) wszystko działa zgodnie z oczekiwaniami :
array(5) {
[0]=> float(88,22)
[1]=> float(88,22)
[2]=> float(88,22)
[3]=> string(9) "88,22 €"
[4]=> string(9) "88,22 €"
}
Edit4:
główną różnicą pomiędzy pracą z S Tempo i pracy z braku konfiguracji przestrzeni przerwa jest wersja ICU:
wersja robocza:
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
wersja nie działa:
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
Pomysł: czy znak € od kodera UTF-8 jest zakodowany (0x20AC), a od klawiatury Latin-1 (0x80)? O ile wiem, funkcja strlen() nie zna znaków Unicode. Jeśli jest używane wewnętrznie przez var_dump(), to wyjaśniałoby to dodatkowy znak. – CodeZombie
Moja aplikacja terminalu (iTerm2) używa Unicode (UTF-8) jako emulacji terminalu. Również ten błąd/zachowanie dzieje się z danych wejściowych z przeglądarki poprzez pola wprowadzania tekstu w formacie HTML. Dodałem wyjście heksowe do wyjaśnienia. – nofreeusername
to plik zapisany jako UTF-8? –