|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2019-08-04 08:44 UTC] cmb@php.net
-Status: Open
+Status: Verified
[2020-10-19 12:51 UTC] cmb@php.net
-Status: Verified
+Status: Closed
-Assigned To:
+Assigned To: cmb
[2020-10-19 12:51 UTC] cmb@php.net
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 03:00:01 2025 UTC |
Description: ------------ PHP's support for locales in its number formatting assumes that 'decimal_point' will be a single char. This is not always the case, however. On my system, for example, locale "ps_AF" has it as "٫" as represented in UTF-8 encoding.[1] PHP uses only the first byte of that, producing "Ù" in the console output. This seems to affect at least string casts and the printf() family of functions. I note though that number_format() is not affected, it works fine when multibyte values are passed for the separators. I reproduce this in PHP 7.0.31, 7.1.20, 7.2.11, 7.3.4, and current git master (5f3ee3afe7). [1]: Note this is not really a Unicode issue though. If the locale had decimal_point set to the string "dec" for some reason, PHP would similarly use only "d". Test script: --------------- <?php echo PHP_VERSION . "\n"; $n = 123456.789; // If this locale doesn't exist on your system or doesn't have a non-ASCII // 'decimal_point', change it to one that does. var_dump( setlocale( LC_NUMERIC, 'ps_AF' ) ); var_dump( localeconv() ); echo "$n\n"; printf( "%.15g\n", $n ); echo number_format( $n, 3, localeconv()['decimal_point'], localeconv()['thousands_sep'] ) . "\n"; Expected result: ---------------- 8.0.0-dev string(5) "ps_AF" array(18) { ["decimal_point"]=> string(2) "٫" ["thousands_sep"]=> string(2) "٬" ["int_curr_symbol"]=> string(0) "" ["currency_symbol"]=> string(0) "" ["mon_decimal_point"]=> string(0) "" ["mon_thousands_sep"]=> string(0) "" ["positive_sign"]=> string(0) "" ["negative_sign"]=> string(0) "" ["int_frac_digits"]=> int(127) ["frac_digits"]=> int(127) ["p_cs_precedes"]=> int(127) ["p_sep_by_space"]=> int(127) ["n_cs_precedes"]=> int(127) ["n_sep_by_space"]=> int(127) ["p_sign_posn"]=> int(127) ["n_sign_posn"]=> int(127) ["grouping"]=> array(1) { [0]=> int(3) } ["mon_grouping"]=> array(0) { } } 123456٫789 123456٫789 123٬456٫789 Actual result: -------------- 8.0.0-dev string(5) "ps_AF" array(18) { ["decimal_point"]=> string(2) "٫" ["thousands_sep"]=> string(2) "٬" ["int_curr_symbol"]=> string(0) "" ["currency_symbol"]=> string(0) "" ["mon_decimal_point"]=> string(0) "" ["mon_thousands_sep"]=> string(0) "" ["positive_sign"]=> string(0) "" ["negative_sign"]=> string(0) "" ["int_frac_digits"]=> int(127) ["frac_digits"]=> int(127) ["p_cs_precedes"]=> int(127) ["p_sep_by_space"]=> int(127) ["n_cs_precedes"]=> int(127) ["n_sep_by_space"]=> int(127) ["p_sign_posn"]=> int(127) ["n_sign_posn"]=> int(127) ["grouping"]=> array(1) { [0]=> int(3) } ["mon_grouping"]=> array(0) { } } 123456Ù789 123456Ù789 123٬456٫789