Formatar moedas ou números decimais com a função number_format() do PHP

A função number_format() do PHP, além de trocar ponto(.) por vírgula(,), também serve para definir quantas casas decimais teremos no valor.

O número que é em Inglês 999.9 fica 999,90 no formato moeda brasileiro.
Além disso, podemos definir se irá exibir algum caracter a cada grupo de milhar(de mil em mil)

string number_format ( float $number, int $decimals, string $dec_point, string $thousands_sep )

podemos definir por:
valor texto number_format($valor_decimal, $casas_decimais,$caracter_definicao_decimal, $caracter_definicao_milhar)


Por exemplo, se quisermos que o número 1000 fique como 1.000, utilizamos a função desta maneira:

$valor = 1000;
echo number_format($valor,0,",",".");

Agora se quisermos que o valor 1,000.9(em formato inglês) tenha o formato 1.000,90(brasileiro), utilize:

$valor = 1,000.9;
echo number_format($valor,2,",",".");

Se não quiser que tenha o ponto(.) entre as casas de milhar, deixe com o última parâmetro vazio:

$valor = 1000.9;
echo number_format($valor,2,",","");

Existe uma maneira gambiarra para formatar número que eu não aconselho a utilizar. Seria algo do tipo:

$valor = 100.9
echo str_replace(".",",",$valor);

Update: Uma maneira de utilizar com números negativos é utilizando abs() e multiplicar por -1:

$valor = -0.54;
if ( $valor < 0 ) {
    $valor = abs($valor);
    $valor = number_format($valor) * -1;
} else {
    $valor = number_format($valor);
}

Encontrei aqui: http://stackoverflow.com/a/6429576/3415716

39 ideias sobre “Formatar moedas ou números decimais com a função number_format() do PHP

  1. Olá leo, Sou novo em php. Mas todos ja foram novos um dia, certo? Minha questão e: quando uso number_format ele arredonda os centavos para 00. Ou seja. quando digito 1520,71 ele fica 1520,00.
    number_format($total1, 2, ‘,’, ‘.’ );
    Usando O campo MySQL decimal(10,2)

  2. Olá!

    Gostaria de saber o que acha sobre QUANDO o número deve ser formatado.

    O sistema todo recebe os dados dos formulários em formato BRL (1.000,00), porém sempre deve ser armazenado como float (1000.00).

    Não podemos confiar no javascript para fazer a conversão, muito menos no usuário.

    Nesse caso, a formatação deve ocorrer na captura do valor antes de enviar ao objeto, ou a formatação deve ocorrer dentro do setter da classe que recebe o valor?

    CAPTURA
    $valor = number2Float($_POST[‘valor’]);
    $objeto->setValor($valor);

    CLASSE
    public function setValor($valor) {
    $this->valor = $valor;
    }

    OU

    CAPTURA
    $objeto->setValor($_POST[‘valor’]);

    CLASSE
    public function setValor($valor) {
    $this->valor = number2Float($valor);
    }

    Estou com esse dilema:
    – Se formatar antes do envio, precisarei fazer isso todas as vezes que receber um valor
    – Se formatar na classe, estarei editando os dados recebidos, o que não me parece uma boa prática

    Gostaria da sua opinião.

    Obrigado!

    • CDS, obrigado pelo seu comentário.

      Em questão a sua pergunta, acredito que não exista um CERTO e ERRADO. Vai do desenvolvedor.

      Por boas práticas, eu normalmente insiro as conversões no set() e get(). Assim deixo que toda a minha aplicação trabalhe com valores que sejam possíveis em minhas operações.

      Espero que te ajude.

  3. Bom dia, excelente blog! parabéns.
    Estou com dificuldade em em mostrar números pequenos em de cálculos para juros de ações.
    ex: se se o numero é -0,45, apos o calculo o sistema escreve 0,00.

    a função que estou usando é:

    .$nombre_format_francais = number_format($finan, 2, ‘,’, ‘ ‘).

    • O campo MySQL decimal(10,2) seria o mais indicado para currency(moeda). http://stackoverflow.com/a/13030401/3415716

      O ideal é converter para o formato informando quais as 2 casas decimais antes de salvar no MySQL, sem nenhum outro caracter.

      Você deve fazer a conversão utilizando o number_format() do php no front-end do seu site, depois de carregar do MySQL. Nada impede, você utilizar o MySQL para formatar, mas a formatação deve ser feita sempre antes de enviar para o MySQL e depois também.

      Espero que ajude

  4. Olá Galera pesquisando na internet achei o blog de vocês muito bacana:
    Estou na seguinte situação tenho um site de venda de imoveis e tenho o código para colocar os valores de cada imóvel so que o formato esta em Inglês e por exemplo quando eu coloco o seguintes numeros: 130000 no front end do site me aparece 130 000 R$ quando teria que aparecer 1.300 00 R$ abaixo o codigo para o formato em inglês:

    /**
    * Format price
    */
    function aviators_price_format($number) {
    $decimals = (int) aviators_settings_get_value('money', 'format', 'decimals');
    $dec_point = aviators_settings_get_value('money', 'format', 'dec_point');
    $thousands_sep = aviators_settings_get_value('money', 'format', 'thousands_sep');

    $symbol = aviators_settings_get_value('money', 'currency', 'sign');
    $before = (bool) aviators_settings_get_value('money', 'currency', 'before');
    $number = number_format((float) $number, $decimals, $dec_point, $thousands_sep);

    if ($before) {
    return sprintf('%s %s', $symbol, $number);
    } else {
    return sprintf('%s %s', $number, $symbol);
    }
    }

    Como passar para o formato da nossa nossa moeda.
    Grato e parabens pelo blog

    • Utilize
      number_format($valor,2,",","");

      Na hora de cadastro do valor no front end em vez de colocar 130000 , coloque 1300 sem 2 zero final ,
      porque voce ja esta acrescentando 2 zero no final do valor number_format($valor,2,",","");

      att

  5. Olá Léo essa questão através do number_format não termina nunca kkkkk

    Estou com uma dúvida vamos ver se vc pode me ajudar, estou editando um Scrip que foi desenvolvido por uma empresa estrangeira. Os valores no site aparecem inteiros por exemplo se digito R$ 200.000 aparece R$ 200, preciso que os valores retornem com pontos não é necessário as casas de centavos. Eu preciso que os valores retornem assim: R$ 2.000, R$ 20.000, R$ 200.000, R$ 2.000.000 a empresa me enviou dois tutoriais com os dois códigos que preciso alterar, os códigos seguem abaixo:

    Primeiro arquivo (property_home_content_residential.phtml)

    Código orginal: <?php echo $this->_currency->getSymbol().$this->_view->escape($entry['property_price']); ?>

    Código formatado: <?php echo $this->_currency-> getSymbol().number_format($this->_view->escape($entry['property_price'])); ?>

    Segundo arquivo ( property_home_content_featured.phtml)

    Código original: <?php echo $this->translator->translator('partial_featured_property_price').' '.$this->_view->escape($entry['property_price']).' '.$this->_currency->getSymbol(); ?>

    Código formatado: <?php echo $this->translator->translator('partial_featured_property_price').' '.number_format($this->_view->escape($entry['property_price'])).' '.$this->_currency->getSymbol(); ?>

    Acredito que preciso inserir os parâmetros: ($valor,0,",",".")

    Como fica esse código alterado?

    • Desculpa a demora Carlos, mas você conseguiu corrigir seu problema?

      Você está usando algum debug? Para debugar, é necessário ir linha após linha e descobrir os valores atuais das variáveis. Em algum momento está convertendo a vírgula por ponto…mas sem debug, é impossível descobrir. No mínimo usando um print_r()

  6. Olá, eu tenho um site ptc é quando o valor da visita é creditado aparece o seguinte erro R$0.450000000002
    irei colocar o codigo abaixo.

    <?
    include('config.php');
    $checkpemail = mysql_query("SELECT id FROM tb_users");
    $pemail_exist = mysql_num_rows($checkpemail);

    $sqryvar="Select sum(amount) from tb_history";
    $iqryvar=mysql_query($sqryvar);
    $tot1=mysql_result($iqryvar,0,0);
    $totals=$tot1;
    if ($totals==''){
    $totalpaid='0.00';
    } else{
    $totalpaid=$tot1;
    }

    $sqryvar="Select sum(visits) from tb_users";
    $iqryvar=mysql_query($sqryvar);
    $tot1=mysql_result($iqryvar,0,0);
    $clickserved=$tot1;
    mysql_close($con);
    ?>

    <table width="100%">

    <tr>
    <td>Por Clique Free</td>
    <td>R$&nbsp;<?php include('config.php');
    $sql = "SELECT * FROM tb_config WHERE item='click' and howmany='1'";
    $result = mysql_query($sql);
    $row = mysql_fetch_array($result);
    echo $row["price"];
    mysql_close($con);?></td>
    </tr>
    <td>Clique Indicado Free</td>
    <td>R$&nbsp;0.003</td>
    </tr>
    <td>Clique Premium</td>
    <td>R$&nbsp;0.02</td>
    </tr>
    <td>Clique Indicado Premium</td>
    <td>R$&nbsp;0.005</td>
    <tr>
    <td>Pagamento Mínimo</td>
    <td>R$&nbsp;<?php include('config.php');
    $sql = "SELECT * FROM tb_config WHERE item='payment' and howmany='1'";
    $result = mysql_query($sql);
    $row = mysql_fetch_array($result);
    echo $row["price"];
    mysql_close($con);
    ?></td>
    </tr>
    <tr>
    <td>Total Usuários</td>
    <td><?php echo $pemail_exist; ?></td>
    </tr>
    <tr>
    <td>Usuários Premium</td>
    <td>2</td>
    </tr>
    <tr>
    <td>Usuários Online</td>
    <td><?php include("onlinesql.php"); ?></td>
    </tr>
    <tr>
    <td>Total Pago</td>
    <td>R$&nbsp;<?php echo $totalpaid?></td>
    </tr>
    <tr>
    <td>Total De Cliques</td>
    <td><?=$clickserved?></td>
    </tr>

    </table>

  7. Pingback: Formatando números com a função number_format() « <?PHProgrammer

  8. Pingback: Formatar números com a função number_format() : FernandoMoreira - Webdesigner e Programador

  9. Já tentei sim e não dá certo. Acabei pensado em outra função, a substr(). Assim eu divido a string em mais strings e depois junto tudo novamente colocando a vírgula. Usando valor negativo inverte-se o ponto de início (substr($v,-2)). A outra parte eu uso strlen() e subtraio duas posições de seu resultado. Isso só para a vírgula ficar no lugar certo. Quanto aos pontos… bem alguns ifs baseados no tamanho da string resolve.
    Não é a maneira mais prática mas resolveu meu problema. Se eu achar algo melhor, é claro que posto aqui com prazer. Muito obrigado pela atenção. Abraço e boa sorte!

    • Be… enquanto não acho algo próprio para resolver esta questão, vou usar esta função que criei.
      Tudo porque eu preciso deixar a digitação em texto para o cliente obedecer a escrita em português. Não quero usar javascript para fazer uma máscara, já que não é em todos os computador que vai funcionar. E o campo no banco de dados é inteiro (para manter os centavos, real estava dando erro), assim eu consigo inserir uma "string" em um campo numérico. Não é o mais bonito mas funciona e o cliente está satisfeito e eu prefiro usar só php. Segue o código da função:

      <?php function em_real($campo){
      // limpar valor texto 1.500.000,59 em inteiro e depois em real formatado
      $vi = trim( $campo);
      $vi = str_replace(".","",$vi); $vi = str_replace(",","",$vi);

      $comp = strlen($vi);

      $v0 = substr($vi,-2); // centavos
      $vv = substr($vi,0, $comp-2); // milares

      return $valor_real = number_format($vv,0,",",".").",". $v0; // formato final
      }
      ?>

      • Alexandre, desculpe a demora, mas acho que divindo por 100 e usando o number_format você tem um resultado mais rápido e mais confiável do que trabalhar com strings!

        Abs e desculpe a demora!

  10. O problema dessa função é que ela é pensada na forma americana de escrita. Imagine algo como um valor Real fosse digitado assim: 125000048 , sem ponto e sem vírgula. Como resolver isso com esta função? impossível, pois retornaria 125.000.048,00 sendo que a intenção era 1.250.000,48. Alguém sabe como resolver isso?
    Boa sorte com o blog e obrigado!

    • ex.:
      $valor = 150;
      echo number_format($valor,2,",",".");

      vai retornar 150,00

      ex&sup2;.:
      $valor = 150.25;
      echo number_format($valor,2,",",".");

      vai retornar 150,25

      • Bem, o problema é quando se digita 15025 (sem o ponto ou vírgula). Esse era o meu problema, o cliente queria digitar direto, sem formatação alguma. Vai entender né!?!
        Mas valeu a boa vontade Pedro. Isso que você menciona está no texto do próprio post e bem explicado e você só o repetiu. Mas isso não serve para o caso de números onde não se coloca ponto ou vírgula mas mesmo assim existe o centavos. Como eu mencionei lá em cima, o 15025 (cento e cinquenta reais e vinte e cinco centavos). Abraço.

          • Olá Leo, não se preocupe quanto a possíveis demora. O que vale é a boa vontade e… imagine só, você está certo: dividir por 100, funcionou! Éra exatamente o que eu precisava e sem nenhuma linha à mais… Agora só tenho um probleminha… hehehe… vou ter de jogar minha função fora hahahaha!!!!
            E pode acreditar que sempre estarei dando uma consultada no seu site.
            Abração e boa sorte!

          • Magina! Sempre que posso tento ajudar todo mundo rsrs!

            Então, na programação é assim. Existem milhares de caminhos para percorrer! O que importa é o resultado final!

            A sua função funcionou, então ta valendo rsrs!

            Tenho um colega de trabalho que diz sempre assim: \”Existe o jeito certo e o que funciona\”

            Você até pode jogar sua função \”fora\”. Mas de qualquer maneira, este problema fez você pensar e pensar e pensar. E esse é o objetivo do programador. Resolver problemas!

            Abs e espero postar mais em breve! Boa sorte pra ti também!

    • ai é um erro de digitação. Aprendemos na escola, se no numero que digitamos não tem ponto nem virgula, ele todo é um inteiro, se vc digita isso 125000048 vc quer isso 125.000.048,00 é a mesma coisa. se vc quer q saia isso 1.250.000,48 deve digitar isso 1250000.48 ou 1250000,48. vc é quem apresenta os decimais para qualquer programa, ate a calculadora.

    • Eu faço assim procuro a virgula, se nao tiver conto length-2 da string e coloco um ponto no meio, dai ja da para usar o numeber_format onde o parametro é com ponto

    • Leo amigo estou sem entender e preciso da sua ajuda, é o seguinte : tenho um input em uma pagina onde permito digitar um valor, na minha classe de negócio se a pessoa tiver digitado 100,00 eu estou usando a função number_format(preg_replace("/[^0-9]/","", $val)/100,2,',','.') para pegar só os números em conjunto com a função number_format para transforma-los em valores R$, mais é ai onde mora o problema, se eu digitar no input o valor 10,000 ele é gravado como 100,00 percebi que se eu tirar o /100 da minha função acima ele aparece certinho como 10.000,00 mais tbm gera um erro se eu digitar 150,23 ele apresenta como 15.023,00, como resolvo isso? desde já obrigado.

      • Thiago, não consegui entender como 150,23 é transformado em 15.023,00. Não faz muito sentido. Tenta colocar a sua regExpress em uma variável separada e dá um print_r() no resultado antes de usar o number_format(). Acredito que o problema esteja aí. Pois a função number_format() sempre funciona.

        Ex:
        $regExprss = preg_replace("/[^0-9]/","", $val);
        print_r($regExpress); //aqui deve estar o problema.

        number_format($regExpress/100,2,',','.');

Deixe uma resposta