Test - PHP Online

Form of PHP Sandbox

Enter Your PHP code here for testing/debugging in the Online PHP Sandbox. As in the usual PHP files, you can also add HTML, but do not forget to add the tag <?php in the places where the PHP script should be executed.



Your result can be seen below.

Result of php executing





Full code of Test.php

  1. <?php
  2.  
  3. class nuts {
  4.   const DEBUG = FALSE;
  5.   private $nb, $decSep, $unit;
  6.   private $parts = array();
  7.   private $separators =
  8.       array(
  9.         "fr-FR" => array(', ', '-', ' ', ' '),
  10.         "en-EN" => array(', ', '-', ' ', ' '),
  11.         "pt-PT" => array(' e ', ' e ', ' e ', ' e ')
  12.       );
  13.   private $units =
  14.       array(
  15.         "USD" => array(
  16.           100,
  17.           "fr-FR" => array('dollar', 'dollars', 'centime', 'centimes', '', ''),
  18.           "pt-PT" => array('dollar', 'dollars', 'cêntimo', 'cêntimos', 'm', 'm'),
  19.           "en-EN" => array('dollar', 'dollars', 'cent', 'cents', '')
  20.         ),
  21.         "EUR" => array(
  22.           100,
  23.           "fr-FR" => array('euro', 'euros', 'centime', 'centimes', '', ''),
  24.           "pt-PT" => array('euro', 'euros', 'cêntimo', 'cêntimos', 'm', 'm'),
  25.           "en-EN" => array('euro', 'euros', 'cent', 'cents', '', '')
  26.         ),
  27.         "t"  => array(
  28.           1000,
  29.           "fr-FR" => array('tonne', 'tonnes', 'kilo', 'kilos', '', ''),
  30.           "pt-PT" => array('tonelada', 'toneladas', 'quilo', 'quilos', 'f', 'm'),
  31.           "en-EN" => array('ton', 'tons', 'kilogram', 'kilograms', '', '')
  32.         )
  33.       );
  34.   private $numbers =
  35.       array(
  36.         "fr-FR" => array(
  37.           0 => array('zéro', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf'),
  38.           1 => array('dix', 'vingt', 'trente', 'quarante', 'cinquante', 'soixante', 'soixante-dix', 'quatre-vingts', 'quatre-vingt-dix'),
  39.           2 => array('cent', 'cents'),
  40.           3 => array('mille', 'mille'),                                            /* Règle 3 */
  41.           6 => array('million', 'millions'),
  42.           9 => array('milliard', 'milliards')
  43.           ),
  44.         "pt-PT" => array(
  45.           0 => array('zero', 'um', 'dois', 'três', 'quatro', 'cinco', 'seis', 'sete', 'oito', 'nove'),
  46.           1 => array('dez', 'vinte', 'trinta', 'quarenta', 'cinquenta', 'sessenta', 'setenta', 'oitenta', 'noventa'),
  47.           2 => array('cem', 'cem', 'f'),
  48.           3 => array('mil', 'mil', 'f'),
  49.           6 => array('milhão', 'milhões', 'm'),
  50.           9 => array('mil milhões', 'mil milhões', 'm')
  51.         ),
  52.         "en-EN" => array(
  53.           0 => array('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'),
  54.           1 => array('ten', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'),
  55.           2 => array('hundred', 'hundred'),
  56.           3 => array('thousand', 'thousand'),                                                             
  57.           6 => array('million', 'millions'),
  58.           9 => array('billion', 'billions')
  59.         )
  60.       );
  61.   private $localExceptions =
  62.       array(
  63.         "fr-FR" => array(
  64.           array("/dix-un/", "onze"),
  65.           array("/dix-deux/", "douze"),
  66.           array("/dix-trois/", "treize"),
  67.           array("/dix-quatre/", "quatorze"),
  68.           array("/dix-cinq/", "quinze"),
  69.           array("/dix-six/", "seize"),
  70.           array("/-un/", " et un"),                                                        /* Règle 1 */
  71.           array('/^et /', ''),
  72.           array("/soixante-onze/", "soixante et onze"),            /* Règle 2 */
  73.           array('/^-/', ''),
  74.           array('/ zéro$/', ""),
  75.           array("/-zéro/", ""),
  76.           array("/cents /", "cent "),                                                      /* Règle 4 */
  77.           array('/cent et/', 'cent'),
  78.           array('/cents et/', 'cents'),
  79.           array('/-$/', ""),                                                        
  80.           array("/vingts-/", "vingt-"),                                              /* Règle 4 */
  81.           array("/un cent/", "cent"),
  82.           array("/^un mille/", "mille"),
  83.           array("/cent millions/", "cents millions"),                      /* Règle 5 */
  84.           array("/cent milliards/", "cents milliards")             /* Règle 5 */
  85.         ),             
  86.         "pt-PT" => array(
  87.           array('/^ e zero$/', 'zero'),
  88.           array('/ zero$/', ''),
  89.           array('/ e zero/', ''),
  90.           array("/dez e um/", "onze"),
  91.           array("/dez e dois/", "doze"),
  92.           array("/dez e três/", "treze"),
  93.           array("/dez e quatro/", "catorze"),
  94.           array("/dez e cinco/", "quinze"),
  95.           array("/dez e seis/", "dezasseis"),
  96.           array("/dez e sete/", "dezassete"),
  97.           array("/dez e oito/", "dezoito"),
  98.           array("/dez e nove/", "dezenove"),
  99.           array("/um e cem/", "cem"),
  100.           array("/dois e cem/", "e duzentos"),
  101.           array('/e duzentos e /', 'duzentos e '),
  102.           array('/três e cem/', 'e trezentos'),
  103.           array('/e trezentos e /', 'trezentos e '),
  104.           array("/quatro e cem/", "e quatro centos"),
  105.           array('/e quatro centos e /', 'quatro centos e '),
  106.           array('/cinco e cem/', 'e quinhentos'),
  107.           array('/e quinhentos e /', 'quinhentos e '),
  108.           array("/seis e cem/", "e seiscentos"),
  109.           array('/e seiscentos e /', 'seiscentos e '),
  110.           array("/sete e cem/", "e setecentos"),
  111.           array('/e setecentos e /', 'setecentos e '),
  112.           array("/oito e cem/", "e oitocentos"),
  113.           array('/e oitocentos e /', 'oitocentos e '),
  114.           array("/nove e cem/", "e novecentos"),
  115.           array('/e novecentos e /', 'novecentos e '),
  116.           array('/cem e /', 'cento e '),
  117.           array('/ e$/', ''),
  118.           array('/^e$/', ''),
  119.           array('/um mil$/', 'mil')
  120.           ),         
  121.         "en-EN" => array(
  122.           array("/ten-one/", "eleven"),
  123.           array("/ten-two/", "twelve"),
  124.           array("/ten-three/", "thirteen"),
  125.           array("/ten-four/", "fourteen"),
  126.           array("/ten-five/", "sixteen"),
  127.           array("/ten-six/", "sixteen"),
  128.           array("/ten-seven/", "seventeen"),
  129.           array("/ten-height/", "eighteen"),
  130.           array("/ten-nine/", "nineteen"),
  131.           array('/^-/', ''),
  132.           array("/-zero/", ""),
  133.           array("/hundred /", "hundred and "),
  134.           array('/hundred-/', 'hundred and '),
  135.           array('/hundred and thousand/', 'hundred thousand'),
  136.           array("/ and zero/", "")
  137.         )
  138.       );
  139.   private $partExceptions = 
  140.       array(
  141.         "fr-FR" => array(
  142.           array("/ zéro/", ""),
  143.           array("/[[:blank:]].zéro/", ""),
  144.           array('/^-/', ''),
  145.           array('/ -/', ' '),
  146.           array('/million$/', "million de"),
  147.           array('/millions$/', "millions de"),
  148.           array('/milliard$/', "milliard de"),
  149.           array('/milliards$/', "milliards de")
  150.         ),
  151.         "pt-PT" => array(
  152.           array('/ zero/', ""),
  153.           array('/^e /', ''),
  154.           array('/milhões$/', 'milhões de'),
  155.           array('/milhão$/', 'milhão de')
  156.           ),
  157.         "en-EN" => array(
  158.           array("/ zero/", ""),
  159.           array("/[[:blank:]].zero/", "")
  160.         )
  161.       );
  162.   private $genderExceptions = 
  163.       array(
  164.         "fr-FR" => array(),
  165.         "pt-PT" => array(
  166.           array('/um/', 'uma'),
  167.           array('/dois/', 'duas'),
  168.           array('/entos/', 'entas')
  169.         ),
  170.         "en-EN" => array()
  171.       );
  172.   private $globalExceptions = 
  173.       array(
  174.         "fr-FR" => array(
  175.           array("/de e/", "d'e")
  176.         ),
  177.         "pt-PT" => array(
  178.         ),
  179.         "en-EN" => array()
  180.       );
  181.                         
  182.   /**
  183.    * @param real $nb Nombre à convertir.
  184.    * @abstract Formats acceptés : 1234 | 12,34 | 12.34 | 12 345.
  185.    * Un seul caractère non numérique sera accepté et considéré comme le séparateur décimal en entrée.
  186.    * @example
  187.    * $obj = new nuts("12345.67", "EUR");
  188.    * $text = $obj->convert("fr-FR");
  189.    * $nb = $obj->getFormated(" ", ",");
  190.    */
  191.   function __construct($nb, $unit){
  192.     // Nettoyages.
  193.     $this->nb = str_replace(' ', '', $nb);                                             // Suppession de tous les espaces.
  194.     $this->nb = preg_replace("/[A-Za-z]/", "", $this->nb);     
  195.     $this->nb = preg_replace("/^0+/", "", $this->nb);                   // Suppression des 0 de tête.
  196.     
  197.     if ($this->nb == '') $this->nb = '0';
  198.     
  199.     $this->unit = $unit;
  200.     
  201.     // Séparateur.
  202.     $this->decSep = preg_replace("/[0-9]/", '', $this->nb);             // On ne garde que ce qui n'est pas numérique
  203.     $this->decSep = substr($this->decSep, -1);                                   // et on prend le dernier des caractères restants.
  204.     
  205.     // Partie entière et partie décimale.
  206.     if ($this->decSep == '') {
  207.       // Pas de partie décimale.
  208.       $this->parts[] = $this->nb;
  209.     } else {
  210.       // Ajout d'un 0 quand il manque devant le séparateur décimal.
  211.       // Noter le double \ pour échapper le séparateur . qui est un opérateur dans les expressions régulières.
  212.       $this->nb = preg_replace("/^\\" . $this->decSep . "/", "0" . $this->decSep, $this->nb);  
  213.     
  214.       $this->parts = explode($this->decSep, preg_replace("/^[0-9] " . $this->decSep . "/", '', $this->nb));
  215.       
  216.       // Nettoyage partie décimale.
  217.       if ($this->parts[1] == ''){
  218.         unset($this->parts[1]);
  219.         $this->decSep = '';
  220.       } else {
  221.         // On coupe la partie décimale au nombre de caractères en fonction du rapport entre unité et sous-unité.
  222.         $this->parts[1] = substr($this->parts[1], 0, strlen($this->units[$this->unit][0]) - 1);
  223.         
  224.         // On bourre avec des 0 de fin.
  225.         while (strlen($this->parts[1]) < strlen($this->units[$this->unit][0]) - 1){
  226.           $this->parts[1] .= '0';
  227.         }
  228.       }
  229.     }
  230.     
  231.     if (nuts::DEBUG) echo "construct : [" . $this->nb . "]";
  232.   }
  233.   
  234.   /**
  235.    * 
  236.    */
  237.   function __destruct(){
  238.   }
  239.   
  240.   /**
  241.    * Module de traduction d'un groupe de 3 digits.
  242.    * 
  243.    * @param string $group Groupe de 3 digits.
  244.    * @param integer $unit Indice de l'unité concernée par $group.
  245.    * @param string $language Langue demandée.
  246.    * @param integer $gender Indice du genre dans le tableau (4 pour l'unité de mesure, 5 pour la sous-unité).
  247.    */
  248.   private function getThree($group, $unit, $language, $gender){
  249.     $return = "";
  250.     
  251.     if ($group == '') $group = 0;
  252.     
  253.     // Centaines.
  254.     if ($group >= 100) {
  255.       $hundreds = floor($group / 100);;
  256.       if ($hundreds == 1) {
  257.         $return .= $this->numbers[$language][0][$hundreds] . $this->separators[$language][3] . $this->numbers[$language][2][0];
  258.       } else {
  259.         $return .= $this->numbers[$language][0][$hundreds] . $this->separators[$language][3] . $this->numbers[$language][2][1];
  260.       }
  261.       
  262.       $tens = $group % 100;           // On enlève les centaines.
  263.     } else {
  264.       $tens = $group;
  265.     }
  266.     
  267.     // Dizaines et unités.
  268.     if ($tens >= 10) {
  269.       $return .= $this->separators[$language][2] . $this->numbers[$language][1][floor($tens / 10) - 1] . $this->separators[$language][1] . $this->numbers[$language][0][$tens % 10];
  270.     } else {
  271.       $return .= $this->separators[$language][1] . $this->numbers[$language][0][(int) $tens];
  272.     }
  273.     
  274.     if ($unit < 3){
  275.       // [0..999].
  276.     } else {
  277.       // 0, 1 ou n ?
  278.       if ($group == 0) {
  279.       } elseif ($group == 1){
  280.         $return .= ' ' . $this->numbers[$language][$unit][0];
  281.       } else {
  282.         $return .= ' ' . $this->numbers[$language][$unit][1];
  283.       }
  284.     }
  285.     
  286.     if (nuts::DEBUG) echo "<br>local a [" . $return . "] ";
  287.     // Exceptions.
  288.     for ($i = 0; $i < count($this->localExceptions[$language]); $i++){
  289.       $return = trim(preg_replace($this->localExceptions[$language][$i][0], $this->localExceptions[$language][$i][1], $return));
  290.       //echo " $i [" . $return . "]";
  291.     }
  292.     
  293.     if (nuts::DEBUG) echo "<br>local b $unit [" . $return . "] ";
  294.     // Exceptions de genre.
  295.     if (   ($this->units[$this->unit][$language][$gender] == 'f' && $unit < 3)
  296.       || ($this->units[$this->unit][$language][$gender] == 'f' && $this->numbers[$language][$unit][2] == 'f')) {
  297.       // L'unité (tonelada) peut être de genre féminin mais les milliers ou millards peuvent être invariables en genre.
  298.       for ($i = 0; $i < count($this->genderExceptions[$language]); $i++){
  299.         $return = trim(preg_replace($this->genderExceptions[$language][$i][0], $this->genderExceptions[$language][$i][1], $return));
  300.       }
  301.     }
  302.     
  303.     if (nuts::DEBUG) echo "<br>local c [" . $return . "] ";
  304.     return $return;
  305.   }
  306.   
  307.   /**
  308.    * Formate la sortie numérique avec séparateurs décimal et des milliers souhaités.
  309.    * 
  310.    * @param string $tSep Séparateur des milliers, en sortie.
  311.    * @param string $dSep Séparateur décimal, en sortie.
  312.    */
  313.   function getFormated($tSep = '', $dSep = '.'){
  314.     if ($tSep == $dSep) {
  315.       // Les 2 séparateurs ne peuvent être identiques > valeurs par défaut.
  316.       $tSep = '';
  317.       $dSep = '.';
  318.     }
  319.     
  320.     $return = $this->format($this->parts[0], $tSep);
  321.     if ($this->decSep == '') {
  322.       // Pas de partie décimale.
  323.       $return .= ' ' . $this->unit;
  324.     } else {
  325.       $return .= $dSep . $this->parts[1] . ' ' . $this->unit;
  326.     }
  327.     
  328.     return $return;
  329.   }
  330.   
  331.   /**
  332.    * Formatage par groupe de 3 digits avec séparateur.
  333.    *
  334.    * @param string $nb Nombre à formater.
  335.    * @param string $sep Séparateur de milliers (espace, virgule).
  336.    * @todo Il faudra s'assurer que le séparateur n'est pas le même que le séparateur décimal qui a été identifié automatiquement.
  337.    */
  338.   private function format($nb, $sep){
  339.     $nb = strrev($nb);
  340.     $n = 0;
  341.     for ($i = 2; $i < strlen($nb); $i++){
  342.       if ($i % 3 == 0){
  343.         $nb = substr($nb, 0, $i + $n) . $sep . substr($nb, $i + $n);
  344.         $n++;
  345.       }
  346.     }
  347.     return strrev(trim($nb));
  348.   }
  349.   
  350.   /**
  351.    * Effectue la conversion en texte de la partie entière ou décimale.
  352.    * 
  353.    * @param string $nb Partie entière ou décimale.
  354.    * @param string $language Langue à utiliser pour la sortie.
  355.    * @param integer $gender Indice du genre dans le tableau (4 pour l'unité de mesure, 5 pour la sous-unité).
  356.    */
  357.   private function part($nb, $language, $gender){
  358.     $return = "";
  359.     
  360.     // Décodage par blocs de 3.
  361.     $groups = explode(' ', $this->format($nb, ' '));
  362.     for ($i = 0; $i < count($groups) ; $i++){
  363.       $return .= $this->getThree($groups[$i], (count($groups) - 1 - $i) * 3, $language, $gender) . ' ';
  364.     }
  365.     $return = trim($return);
  366.  
  367.     if (nuts::DEBUG) echo "<br>part a : [" . $return . "]";
  368.     // Exceptions.
  369.     for ($i = 0; $i < count($this->partExceptions[$language]); $i++){
  370.       $return = trim(preg_replace($this->partExceptions[$language][$i][0], $this->partExceptions[$language][$i][1], $return));
  371.     }
  372.     
  373.     if (nuts::DEBUG) echo "<br>part b : [" . $return . "]";
  374.     return $return;
  375.   }
  376.  
  377.   /**
  378.    * Demande la conversion en texte de chaque partie et ajoute les unités.
  379.    * 
  380.    * @param string $language Langue à utiliser pour la sortie.
  381.    */
  382.   function convert($language){
  383.     // Partie entière.
  384.     $return = $this->part($this->parts[0], $language, 4) . " ";
  385.     $return .= ($this->parts[0] > 1) ? $this->units[$this->unit][$language][1] : $this->units[$this->unit][$language][0];
  386.     
  387.     // Exceptions.
  388.     for ($i = 0; $i < count($this->globalExceptions[$language]); $i++){
  389.       $return = trim(preg_replace($this->globalExceptions[$language][$i][0], $this->globalExceptions[$language][$i][1], $return));
  390.     }
  391.     
  392.     // Partie décimale.
  393.     if (count($this->parts) == 2){
  394.       $return .= $this->separators[$language][0] . $this->part($this->parts[1], $language, 5) . " ";
  395.       $return .= ($this->parts[1] > 1) ? $this->units[$this->unit][$language][3] : $this->units[$this->unit][$language][2];
  396.     }
  397.     
  398.     if (nuts::DEBUG) echo "<br>";
  399.     return $return;
  400.   }
  401. }
  402.  
  403. $obj = new nuts("12345.67", "EUR");
  404. $text = $obj->convert("fr-FR");
  405. $nb = $obj->getFormated(" ", ",");
  406.  
  407. ?>
File Description
  • Test
  • PHP Code
  • 02 May-2022
  • 14.93 Kb
You can Share it: