2017-04-02 2 views
0

Après beaucoup de recherches, je me sers en fait la fonction suivante aux numéros de format pour les paramètres régionaux setted par l'utilisateur:numéros PHP formating du paramètre régional et à l'arrière

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

Je vais l'utiliser pour les numéros de format de DB .

Mais si j'ai un formulaire où un utilisateur peut entrer un nombre, j'ai besoin d'une fonction pour le reformater afin que je puisse enregistrer dans la base de données. Ici, je trouve cette solution:

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

Cela fonctionne avec la plupart des endroits que j'ai testé mais pas avec tout le monde! À titre d'exemple: si j'utilise arabe (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 

Comment formater un lieu numéro entré de manière sécurisée « retour » pour en format? Ou existe-t-il un moyen de détecter tout type de format numérique et de le formater en format de sorte que je puisse l'enregistrer dans la base de données?

Répondre

0

Alors, je ne sais pas vraiment si cela est une bonne solution ou non - mais il semble fonctionner très bien:

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

Je vais vérifier le dernier point ou une virgule et selon ce format I le nombre, la fonction renvoie le même nombre de décimales que le nombre d'origine. il y a un bug « connu »: si quelqu'un entre dans un nombre entier comme 1.000.000 ou 1.000.000 retourne 1000000.

À titre d'exemple:

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) 

Ce serait bien si quelqu'un peut poster un commentaire si ce est un bon moyen ou pas ou une réponse avec une meilleure solution :)