经过大量研究后,我实际上使用以下函数将数字格式化为用户设置的语言环境:
function number_format_i18n($number, $decimals=0) {
$locale = localeconv();
return number_format($number,$decimals, $locale['decimal_point'], $locale['thousands_sep']);
}
我将使用它来格式化DB中的数字。
但是如果我有一个用户可以输入数字的表单,我需要一个函数来格式化它,这样我就可以保存到数据库中。在这里,我找到了这个解决方案:
function number_format_en($number) {
// $_SESSION['lang']['locale'] has the locale like de_DE, ar_AE, tr_TR, ...
$fmt = numfmt_create($_SESSION['lang']['locale'], NumberFormatter::DECIMAL);
return numfmt_parse($fmt, $number);
}
这适用于我测试的大多数语言环境,但不适合所有人!举个例子:如果我使用阿拉伯语(ar_AE):
$randomNumber = 3171003633.95;
$number2locale = number_format_i18n($randomNumber, 2);
// works as expected: 3,171,003,633.95
// now format it back:
$locale2number = number_format_en($number2locale);
// here I get this: 3.171
如何以安全的方式“返回”格式化格式化区域设置输入的数字?或者有没有办法检测任何类型的数字格式并将其格式化为格式化,以便将其保存在数据库中?
答案 0 :(得分:0)
所以,不知道这是否是一个好的解决方案 - 但似乎工作正常:
function number_format_en($number) {
// first remove everything execpt -,.
$cleanNumber = preg_replace('/[^\\d-,.]+/', '', $number);
$last_dot = strrpos($cleanNumber, '.');
$last_comma = strrpos($cleanNumber, ',');
if($last_dot !== false || $last_comma !== false) {
if($last_dot > $last_comma) { // decimal seperator = dot
$decimal_point = '.';
if(substr_count($cleanNumber, '.') > 1) {
// could be totaly wrong 1,234.567.890
// or there are no decimals 1.234.567.890
// removing all dots and commas and returning the value
return preg_replace('/[^\\d-]+/', '', $cleanNumber);
}
} else { // decimal seperator = comma
$decimal_point = ',';
if(substr_count($cleanNumber, ',') > 1) {
// could be totaly wrong 1.234,567,890
// or there are no decimals 1,234,567,890
// removing all dots and commas and returning the value
return preg_replace('/[^\\d-]+/', '', $cleanNumber);
}
}
} else { // no decimals
$decimal_point = false;
$decimals = 0;
}
if($decimal_point !== false) {
// if decimals are delivered, get the count of them
$length = strlen($cleanNumber);
$position = strpos($cleanNumber, $decimal_point);
$decimals = $length - $position - 1;
if($decimal_point == '.') {
// remove all commas if seperator = .
$cleanNumber = str_replace(',', '', $cleanNumber);
} elseif($decimal_point == ',') {
// remove all dots if seperator = ,
$cleanNumber = str_replace('.', '', $cleanNumber);
// now switch comma with dot
$cleanNumber = str_replace(',', '.', $cleanNumber);
}
}
return $cleanNumber;
}
我将检查最后一个点或逗号,并根据我格式化数字,函数返回与原始数字相同的小数位数。有一个“已知”错误:如果有人输入完整的数字,如1.000.000或1,000,000,则返回1000000。
举个例子:
number_format_en('1.234.567,89') // 1234567.89
number_format_en('-1,234,567.89') // -1234567.89
number_format_en('1.234.567.89') // 123456789 (only dots)
number_format_en('1,234,567,89') // 123456789 (only commas)
如果有人可以发表评论,如果这是一个好方法或者是一个更好的解决方案的答案,那将会很好:)