PHP: формат номера в локальном формате
Я хочу отформатировать номер 3253454 для посетителей моего сайта.
Если я использую встроенную функцию number_format, я получаю: 3,253,454, что отлично подходит для Великобритании и США, однако в большинстве других стран используется 3.253.454
У меня много международных посетителей.
Может ли кто-нибудь дать мне указатель на лучшую практику здесь?
В идеале я хочу получить локализацию браузера и соответствующим образом отформатировать номер. Возможно ли это в PHP?
Ответы
Ответ 1
Если вы развертываете локализованный веб-сайт, вам захочется убедиться, что вы setlocale(). Чтобы избавиться от yaauie выше сообщения, я добавлю что-то вроде следующего фрагмента кода в ваш код инициализации:
$locale = ( isset($_COOKIE['locale']) ) ?
$_COOKIE['locale'] :
$_SERVER['HTTP_ACCEPT_LANGUAGE'];
setlocale(LC_ALL, $locale);
Затем мы модифицируем указанную выше функцию number_format_locale()
, чтобы выглядеть так:
function number_format_locale($number,$decimals=2) {
$locale = localeconv();
return number_format($number,$decimals,
$locale['decimal_point'],
$locale['thousands_sep']);
}
Конечно, в идеальном мире, в зависимости от платформы, которую вы развертываете, и какой версии локали вы установили, вам, возможно, придется кодировать некоторые нарушения. Но настройка локали поможет с деньгами, цифрами и датами.
Ответ 2
string number_format (float $number, int $decimals, string $dec_point, string $thousands_sep)
см. php doku для number_format
Еще одна полезная ссылка может быть Zend_Locale из Zend Framework - она может определять ваш язык пользователя, а также помогает с форматированием номера/валюты
Ответ 3
Может быть, попробуйте подход независимо от установки глобальной локали для всех скриптов?
Получить пользовательский язык:
$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 Data Repository.
Ответ 4
От 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;
}
}
?>
Это похоже на то, что вы ищете.:)
Ответ 5
PHP тем временем предлагает класс NumberFormatter, который идеально подходит для этой цели:
http://php.net/manual/de/class.numberformatter.php
Ответ 6
Вы можете использовать переменную сервера 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);
}
Ответ 7
На самом деле это довольно сложно. Этот класс отлично справляется с этим: http://www.webreference.com/programming/Globalize-Web-Applications03/
Ответ 8
В моем проекте я использую Zend Framework. В этом случае я использую такую вещь:
$locale = new Zend_Locale('fr_FR');
$number = Zend_Locale_Format::toNumber(2.5, array('locale' => $locale));
// will return 2,5
print $number;