Я хочу отформатировать номер 3253454 для посетителей моего сайта.
Если я использую встроенную функцию number_format, я получаю: 3,253,454, что отлично подходит для Великобритании и США, однако в большинстве других стран используется 3.253.454
У меня много международных посетителей.
Может ли кто-нибудь дать мне указатель на лучшую практику здесь?
В идеале я хочу получить локализацию браузера и соответствующим образом отформатировать номер. Возможно ли это в PHP?
Если вы размещаете локализованный веб-сайт, вам захочется убедиться, что вы setlocale () . Чтобы избавиться от вышеуказанного сообщения yaauie, я бы добавил в код инициализации что-то вроде следующего фрагмента кода:
$locale = ( isset($_COOKIE['locale']) ) ? $_COOKIE['locale'] : $_SERVER['HTTP_ACCEPT_LANGUAGE']; setlocale(LC_ALL, $locale);
Затем мы модифицируем number_format_locale()
выше функцию number_format_locale()
, чтобы выглядеть так:
function number_format_locale($number,$decimals=2) { $locale = localeconv(); return number_format($number,$decimals, $locale['decimal_point'], $locale['thousands_sep']); }
Конечно, это идеальный мир, в зависимости от платформы, на которую вы развертываетесь, и какой версии установленных вами языковых файлов вам, возможно, придется кодировать некоторые нарушения. Но настройка локали поможет с деньгами, цифрами и датами.
string number_format (float $number, int $decimals, string $dec_point, string $thousands_sep)
см. php doku для number_format
Еще одной полезной ссылкой может быть Zend_Locale из Zend Framework – она может определять язык вашего пользователя, а также помогать с форматированием чисел / валют
Может быть, попробуйте подход независимо от установки глобальной локали для всех скриптов?
Получить локализацию пользователя:
$locale = ( isset($_COOKIE['locale']) ) ? $_COOKIE['locale'] : $_SERVER['HTTP_ACCEPT_LANGUAGE'];
Отформатируйте число:
Я рекомендую использовать PHP NumberFormatter . Это подход ООП, в котором используется библиотека ICU .
$formatStyle=NumberFormatter::DECIMAL; $formatter= new NumberFormatter($locale, $formatStyle); echo $formatter->format(3253454);//proper output depending on locale
Вы можете использовать много разных форматов стилей, например: DECIMAL, CURRENCY или PERCENT. Подробнее читайте здесь .
Это лучший способ форматирования чисел, потому что он зависит от глобального репозитория данных Unicode Common Locale .
С http://us3.php.net/manual/en/function.number-format.php#76448 :
<?php function strtonumber( $str, $dec_point=null, $thousands_sep=null ) { if( is_null($dec_point) || is_null($thousands_sep) ) { $locale = localeconv(); if( is_null($dec_point) ) { $dec_point = $locale['decimal_point']; } if( is_null($thousands_sep) ) { $thousands_sep = $locale['thousands_sep']; } } $number = (float) str_replace($dec_point, '.', str_replace($thousands_sep, '', $str)); if( $number == (int) $number ) { return (int) $number; } else { return $number; } } ?>
Это похоже на то, что вы ищете. 🙂
Тем временем PHP предлагает класс NumberFormatter, который идеально подходит для этой цели:
На самом деле это довольно сложно. Этот класс справляется с этим очень хорошо: http://www.webreference.com/programming/Globalize-Web-Applications03/
В моем проекте я использую Zend Framework. В этом случае я использую такую вещь:
$locale = new Zend_Locale('fr_FR'); $number = Zend_Locale_Format::toNumber(2.5, array('locale' => $locale)); // will return 2,5 print $number;
Вы можете использовать переменную сервера HTTP_ACCEPT_LANGUAGE, чтобы угадать их язык и ожидаемый формат числа.
Если бы я реализовал это, я бы разрешил пользователю задавать предпочтение переопределить догадываться, и моя функция будет выглядеть так:
function number_format_locale($number,$decimals=2) { $locale = ( isset($_COOKIE['locale']) ? $_COOKIE['locale'] : $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) switch($locale) { case 'en-us': case 'en-ca': $decimal = '.'; $thousands = ','; break; case 'fr': case 'ca': case 'de': case 'en-gb': $decimal = ','; $thousands = ' '; break; case 'es': case 'es-mx': default: $decimal = ','; $thousands = ' '; } return $number_format($number,$decimals,$decimal,$thousands); }