2017-04-02 11 views
0

多くの研究の後、私は実際にフォーマット番号にユーザーによってsettedロケールに次の関数を使用しています:PHPの整形ロケールに数字とバック

function number_format_i18n($number, $decimals=0) { 
    $locale = localeconv(); 
    return number_format($number,$decimals, $locale['decimal_point'], $locale['thousands_sep']); 
} 

私はDBからの形式番号にこれを使用します。

しかし、ユーザーが数字を入力できるフォームがある場合は、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 

がどのように私は「戻る」専用形式に安全な方法で番号を入力ロケールをフォーマットすることができますか?または、numberformatの種類を検出し、en-formatにフォーマットしてDBに保存できる方法はありますか?

答えて

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; 
} 

私は最後のドットやコンマをチェックし、そのIフォーマットに依存します数値関数は元の数値と同じ小数点以下の桁数を返します。 「既知」のバグがあります:誰かが、この場合はコメントを投稿することができた場合

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) 

がいいだろう:誰かが1.000.000や1,000,000のような完全な番号を入力した場合には、一例として1000000

を返します。良い方法であるかどうか、またはより良い解決策で答えが得られます:)

関連する問題