Bom dia, queridos leitores!
All right with you?
Mais uma vez, estou trazendo uma função que uso em meus projetos, e a uso sempre que preciso escrever o valor de um número por extenso, o que não é uma situação tão incomum, não é verdade?
Adicionei 2 parâmetros booleanos opcionais
- $bolExibirMoeda: Define se a função vai adicionar uma referência à moeda (centavos, real, etc)
- $bolPalavraFeminina: Define se a função vai retornar duzentos ou duzentas, por exemplo.
Para filtrar melhor o parâmetro de entrada $valor, eu utilizei a função removerFormatacaoNumero, no qual já falei sobre ela aqui no blog, no post Removendo formatação de um número no PHP.
Como se costume, encapsulei a função numa classe e a criei de forma estática, para não precisar instanciar a classe sempre que eu precisar utilizar a função.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
<?php class clsTexto { public static function valorPorExtenso( $valor = 0, $bolExibirMoeda = true, $bolPalavraFeminina = false ) { $valor = self::removerFormatacaoNumero( $valor ); $singular = null; $plural = null; if ( $bolExibirMoeda ) { $singular = array("centavo", "real", "mil", "milhão", "bilhão", "trilhão", "quatrilhão"); $plural = array("centavos", "reais", "mil", "milhões", "bilhões", "trilhões","quatrilhões"); } else { $singular = array("", "", "mil", "milhão", "bilhão", "trilhão", "quatrilhão"); $plural = array("", "", "mil", "milhões", "bilhões", "trilhões","quatrilhões"); } $c = array("", "cem", "duzentos", "trezentos", "quatrocentos","quinhentos", "seiscentos", "setecentos", "oitocentos", "novecentos"); $d = array("", "dez", "vinte", "trinta", "quarenta", "cinquenta","sessenta", "setenta", "oitenta", "noventa"); $d10 = array("dez", "onze", "doze", "treze", "quatorze", "quinze","dezesseis", "dezessete", "dezoito", "dezenove"); $u = array("", "um", "dois", "três", "quatro", "cinco", "seis","sete", "oito", "nove"); if ( $bolPalavraFeminina ) { if ($valor == 1) { $u = array("", "uma", "duas", "três", "quatro", "cinco", "seis","sete", "oito", "nove"); } else { $u = array("", "um", "duas", "três", "quatro", "cinco", "seis","sete", "oito", "nove"); } $c = array("", "cem", "duzentas", "trezentas", "quatrocentas","quinhentas", "seiscentas", "setecentas", "oitocentas", "novecentas"); } $z = 0; $valor = number_format( $valor, 2, ".", "." ); $inteiro = explode( ".", $valor ); for ( $i = 0; $i < count( $inteiro ); $i++ ) { for ( $ii = mb_strlen( $inteiro[$i] ); $ii < 3; $ii++ ) { $inteiro[$i] = "0" . $inteiro[$i]; } } // $fim identifica onde que deve se dar junção de centenas por "e" ou por "," ;) $rt = null; $fim = count( $inteiro ) - ($inteiro[count( $inteiro ) - 1] > 0 ? 1 : 2); for ( $i = 0; $i < count( $inteiro ); $i++ ) { $valor = $inteiro[$i]; $rc = (($valor > 100) && ($valor < 200)) ? "cento" : $c[$valor[0]]; $rd = ($valor[1] < 2) ? "" : $d[$valor[1]]; $ru = ($valor > 0) ? (($valor[1] == 1) ? $d10[$valor[2]] : $u[$valor[2]]) : ""; $r = $rc . (($rc && ($rd || $ru)) ? " e " : "") . $rd . (($rd && $ru) ? " e " : "") . $ru; $t = count( $inteiro ) - 1 - $i; $r .= $r ? " " . ($valor > 1 ? $plural[$t] : $singular[$t]) : ""; if ( $valor == "000") $z++; elseif ( $z > 0 ) $z--; if ( ($t == 1) && ($z > 0) && ($inteiro[0] > 0) ) $r .= ( ($z > 1) ? " de " : "") . $plural[$t]; if ( $r ) $rt = $rt . ((($i > 0) && ($i < = $fim) && ($inteiro[0] > 0) && ($z < 1)) ? ( ($i < $fim) ? ", " : " e ") : " ") . $r; } $rt = mb_substr( $rt, 1 ); return($rt ? trim( $rt ) : "zero"); } } ?> |
Alguns exemplos de uso da função:
1 2 3 4 5 6 7 8 9 10 11 |
//Carregamos a classe para a memória require_once("classes/clsTexto.php"); //Vai exibir na tela "um milhão, quatrocentos e oitenta e sete mil, duzentos e cinquenta e sete e cinquenta e cinco" echo clsTexto::valorPorExtenso("R$ 1.487.257,55", false, false); //Vai exibir na tela "um milhão, quatrocentos e oitenta e sete mil, duzentos e cinquenta e sete reais e cinquenta e cinco centavos" echo clsTexto::valorPorExtenso("R$ 1.487.257,55", true, false); //Vai exibir na tela "duas mil e setecentas e oitenta e sete" echo clsTexto::valorPorExtenso("2787", false, true); |
Excelente código… Top!!
Mas… Eu tentei adaptar para valores maiores e não deu. Complementei os arrays de texto com quintilhão, sextilhão etc e suas versões no plural também, mas dá erro. Gostaria de utilizar até centilhão. Tem ideia de como poderia complementar de maneira adequada e correta? É para um projeto científico.
Obrigado pela ajuda meu caro, você é sênior poderia me indicar uns cursos pls ?
preciso dessa função sem a parte dos reais. tipo 1.35 (Um ponto Trinta e Cinco)
Esta com erro na linha 84.
PHP Parse error: syntax error, unexpected ‘=’ in /home/sigefonline/public_html/sigefonline/view/admin/classes/clsTexto.php on line 84
Muito obrigado por compartilhar este código! Rolou um syntax error, para corrigir eu fiz assim:
Na última linha, do último for temos um ternário com este trecho:
($i < = $fim)
trocamos por:
($i <= $fim)
boa tarde,
E se o número for decimal?
No código actual ele lê como se fosse inteiro? consegue ajudar?
Muito obrigado, me ajudou muito.
Um abraço a partir da Guiné-Bissau em África.
Conseguiu resolver , pois o meu , esta com o mesmo error.
Valeu demais pelas duas funções
Obrigado, Ralph. Espero ter ajudado
Será que fiz algo errado?
Parse error: syntax error, unexpected ‘=’ in C:\xampp\htdocs\moeda\clsTexto.php on line 85
$rt = $rt . ((($i > 0) && ($i 0) && ($z < 1)) ? ( ($i < $fim) ? ", " : " e ") : " ") . $r;
Conseguiu resolver? Se ainda tá com dificuldade, me chama no privado
Estou com esse erro ai.
Dirceu, muitíssimo obrigado por compartilhar!
Favor corrigir o “dezessete”
Fala Eder, beleza? Agora o “dezessete” está correto. 🙂
Obrigado pela observação
Olá Linces! Como você está ?
Conforme citado no início desse post, essa função está disponível no post https://www.dirceuresende.com/blog/removendo-formatacao-de-um-numero-no-php/
Qualquer dúvida, é só falar.
PHP Fatal error: Uncaught Error: Call to undefined method clsTexto::removerFormatacaoNumero()
Obrigado ! meu ajudou aqui
Olá como se corrige esse erro que o marceltoniote falou acima
Vlw, amigo! Sua classe dei um “adianto” muito bom no meu projeto.
Ótimo traballho!
Boa sorte…
Obrigado pelo feedback, svicente99! Qualquer dúvida, é só falar.
Muito bom Dirceu, ajudou bastante.
Olá, obrigado por disponibilizar o código. Este existe no github?
Segue um ajuste que precisei fazer:
Linha 89: return($rt ? trim( $rt ) : “zero”.($bolExibirMoeda ? ” reais e zero centavos” : “” ));
Orlando, boa tarde.
Obrigado pelo feedback. Esse código não está disponível no github, só aqui mesmo.
Abraço!
No meu está dando o seguinte erro:
Fatal error: Call to undefined method extenso::removerFormatacaoNumero() in C:\Servidores_PHP\teste_mdl\extenso\extenso.php on line 10
Apenas troquei o nome da classe para ‘extenso’.
Agradeço uma ajuda desde já!
Marconi, você trocou o nome da classe também ou somente o nome do arquivo? Esse erro geralmente ocorre em objetos estáticos quando o nome da classe está errado ou o método não existe
Bom dia,
Amigo eu estou com esse erro:
Fatal error: Call to undefined method clsTexto::removerFormatacaoNumero() in D:\xampp\htdocs\escola2\classes\clsTexto.php on line 8
Ops falha minha, resolvido!
Tudo bem, Marcelo. Qualquer dúvida é só me avisar.
Galera tem uma lib muito boa que faz a mesma coisa só que diferente. segue os links:
github: https://github.com/malukenho/speaknumber
packages: https://packagist.org/packages/malukenho/speaknumber
OBS: não estou desmerecendo o trabalho do amigo, só estou dando uma nova alternativa de uma lib.
Edinaldo, obrigado pela visita e pela dica dessa lib. Acredito que a solução do post seja mais simples de implementar, mas essa lib que você compartilhou me parece ser mais completa.
Valeu!
Max, você pode alterar o retorno da função e utilizar a função ucfirst:
Exemplo: return($rt ? ucfirst(strtolower(trim( $rt ))) : “zero”);
É verdade… nem tinha lembrado disso. Muito obrigado.!
Muito bom. Como seria para capitalizar somente a primeira palavra?
Obrigado meu amigo, me ajudou muito.
Obrigado pelo snippet, vai me ser muito util
não consegui usar nao.