Кто-нибудь знает, как преобразовать число, такое как 1, 2 или 3, в их текстовую версию (один, два, три) в PHP? Мне нужно конвертировать только от 1 до 99. Я знаю, что могу написать огромное предложение switch, но это было бы смешно.
у груши есть пакет Numbers_Words :
$ numberToWord = new Numbers_Words (); echo $ numberToWords-> toWords (200);
Вот один, который я написал в колледже. Он включает поддержку отрицательных чисел. Я знаю, что некоторые способы можно сократить и / или очистить, но, эй, это хорошо работает для любого целого!
/** Converts an integer to its textual representation. @param num the number to convert to a textual representation @param depth the number of times this has been recursed */ function readNumber($num, $depth=0) { $num = (int)$num; $retval =""; if ($num < 0) // if it's any other negative, just flip it and call again return "negative " + readNumber(-$num, 0); if ($num > 99) // 100 and above { if ($num > 999) // 1000 and higher $retval .= readNumber($num/1000, $depth+3); $num %= 1000; // now we just need the last three digits if ($num > 99) // as long as the first digit is not zero $retval .= readNumber($num/100, 2)." hundred\n"; $retval .=readNumber($num%100, 1); // our last two digits } else // from 0 to 99 { $mod = floor($num / 10); if ($mod == 0) // ones place { if ($num == 1) $retval.="one"; else if ($num == 2) $retval.="two"; else if ($num == 3) $retval.="three"; else if ($num == 4) $retval.="four"; else if ($num == 5) $retval.="five"; else if ($num == 6) $retval.="six"; else if ($num == 7) $retval.="seven"; else if ($num == 8) $retval.="eight"; else if ($num == 9) $retval.="nine"; } else if ($mod == 1) // if there's a one in the ten's place { if ($num == 10) $retval.="ten"; else if ($num == 11) $retval.="eleven"; else if ($num == 12) $retval.="twelve"; else if ($num == 13) $retval.="thirteen"; else if ($num == 14) $retval.="fourteen"; else if ($num == 15) $retval.="fifteen"; else if ($num == 16) $retval.="sixteen"; else if ($num == 17) $retval.="seventeen"; else if ($num == 18) $retval.="eighteen"; else if ($num == 19) $retval.="nineteen"; } else // if there's a different number in the ten's place { if ($mod == 2) $retval.="twenty "; else if ($mod == 3) $retval.="thirty "; else if ($mod == 4) $retval.="forty "; else if ($mod == 5) $retval.="fifty "; else if ($mod == 6) $retval.="sixty "; else if ($mod == 7) $retval.="seventy "; else if ($mod == 8) $retval.="eighty "; else if ($mod == 9) $retval.="ninety "; if (($num % 10) != 0) { $retval = rtrim($retval); //get rid of space at end $retval .= "-"; } $retval.=readNumber($num % 10, 0); } } if ($num != 0) { if ($depth == 3) $retval.=" thousand\n"; else if ($depth == 6) $retval.=" million\n"; if ($depth == 9) $retval.=" billion\n"; } return $retval; }
Не совсем идеальный, но по крайней мере лучше, чем «огромный оператор switch»:
$numbermappings = array("zero", "one","two","three", "four" .... "ninetynine"); echo $numbermappings[4]; // four
Вам все равно придется писать этот огромный массив, хотя ..
См. Эту функцию в действии :
function N2L($number) { $result = array(); $tens = floor($number / 10); $units = $number % 10; $words = array ( 'units' => array('', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eightteen', 'Nineteen'), 'tens' => array('', '', 'Twenty', 'Thirty', 'Fourty', 'Fifty', 'Sixty', 'Seventy', 'Eigthy', 'Ninety') ); if ($tens < 2) { $result[] = $words['units'][$tens * 10 + $units]; } else { $result[] = $words['tens'][$tens]; if ($units > 0) { $result[count($result) - 1] .= '-' . $words['units'][$units]; } } if (empty($result[0])) { $result[0] = 'Zero'; } return trim(implode(' ', $result)); }
Это пакет PEAR, который делает это. Он имеет номер WAY выше 99 и является многоязычным, поэтому он может быть более тяжелым, чем вам нужно, но все же стоит проверить:
В итоге мне пришлось написать это для теста на кодирование во время собеседования. Вы можете увидеть мой последний код в Github: https://github.com/mangs/integers2words
Для удобства здесь представлен класс DemoLibrary, который реализует эту функцию int2str () (все члены класса могут поддерживать только функцию int2str()
):
<?php /** * Demo library class intended to be added to in the future */ class DemoLibrary { /***** NOTE: a const cannot be an array in PHP, so making these arrays static is the next best thing *****/ /** * @var array $_numbersUnder20 Array containing the word associated with the index's number value */ private static $_numbersUnder20 = [ 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen' ]; /** * @var array $_tensDigits Array containing all tens digit values except 10 */ private static $_tensDigits = [ 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety' ]; /** * @var array $_orderOfMagnitude Array containing the higher-order digit values; can also be * thought of as the order of magnitude of the target digit */ private static $_orderOfMagnitude = [ // Stopped at "quintillion" because the maximum PHP int value on 64-bit Linux is // 9,223,372,036,854,775,807 (aka 2^63 - 1 because PHP doesn't support unsigned ints) 'thousand', 'million', 'billion', 'trillion', 'quadrillion', 'quintillion' ]; /** * Recursively calculates the string-, word-based equivalent of the target integer * * @param integer $num Integer whose value will be converted to a word-based string * @param boolean $recursive Determines if the currently-executing code is being called * recursively; allows for non-recursive 0 to be converted to "zero" * otherwise use an empty string * * @throws InvalidArgumentException if the first argument is not of type int * * @return string Partially- or fully-built word-based representation of the target integer */ private function _integerToWords($num, $recursive=false) { // Ensure a valid integer if(!is_int($num)) { throw new InvalidArgumentException( __FUNCTION__ . ' expects parameter 1 to be of type integer; actual type: ' . gettype($num) ); } /***** Perform the int to string conversion based on the size of $num *****/ // Negative if($num < 0) { return 'negative ' . $this->_integerToWords(-1 * $num, true); } // 0 or no value in the lowest digits if($num === 0) { return $recursive ? '' : 'zero'; } // 1-19 if($num < 20) { return self::$_numbersUnder20[$num]; } // 20 - 99 if($num < 100) { $highDigitValue = intval(floor($num / 10) - 2); // Value of the highest-order digit $remainingValue = $num % 10; // Value of the remaining digits return self::$_tensDigits[$highDigitValue] . '-' . $this->_integerToWords($remainingValue, true); } // 100 - 999 if($num < 1000) { $highDigitValue = intval(floor($num / 100)); // Value of the highest-order digit $remainingValue = $num % 100; // Value of the remaining digits return $this->_integerToWords($highDigitValue, true) . '-hundred ' . $this->_integerToWords($remainingValue, true); } // 1,000+ $quotient = $num; $divideCount = 0; while($quotient >= 1000) { $quotient /= 1000; ++$divideCount; } $highDigitValue = intval(floor($quotient)); // Value of the highest-order digit $remainingValue = $num - ($highDigitValue * pow(1000, $divideCount)); // Value of the remaining digits return $this->_integerToWords($highDigitValue, true) . '-' . self::$_orderOfMagnitude[$divideCount - 1] . ' ' . $this->_integerToWords($remainingValue, true); } /** * @api * * Calculates the string-, word-based equivalent of the target integer * * @param integer $num Integer whose value will be converted to a word-based string * * @return string Fully-built word-based representation of the target integer */ public function int2str($num) { return trim($this->_integerToWords($num), "- \t\n\r\0\x0B"); } }