Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

M. Simão

Zero à esquerda em variável gerando comportamento estranho no PHP

Recommended Posts

Oi pessoal,

 

Estou desenvolvendo uma aplicação que precisa tratar o CEP dos Correios e me deparei com algo que não tinha visto ainda no PHP, vou colar abaixo um código simples para ficar mais fácil o entendimento do problema.

 

<?php

 

$numero = 008;

 

print $numero;

 

?>

 

Rodando o código acima em dois servidores diferentes, o print exibiu 0 ao invés de 8. Tive outros comportamentos estranhos ao comparar números que tinham zeros à esquerda.

 

A solução mais simples seria eliminar os zeros à esquerda, afinal são zeros à esquerda, o problema é que no banco de dados que estou trabalhando os CEPs de São Paulo tem os zeros à esquerda e para ser bem sincero fiquei inquieto com esse comportamento do PHP e gostaria de saber o motivo.

 

Alguém aí já se deparou com isso? Conseguiu encontrar alguma explicação?

 

Um abraço!

Compartilhar este post


Link para o post
Compartilhar em outros sites

$valor = 9;

print str_pad($valor, 10); >> retorno "9

print str_pad($valor, 10, "0", STR_PAD_LEFT); >> retorno "0000000009"

 

 

str_pad($valor, TOTAL DE CARACTERES, "CARACTERE A SER ADICIONADO", LUGAR,no caso esquerda)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Alguém aí já se deparou com isso? Conseguiu encontrar alguma explicação?

Explicação: http://www.php.net/manual/pt_BR/language.types.integer.php

 

Sintaxe

 

Inteiros podem ser especificados em notação decimal (base 10), hexadecimal (base 16) ou octal (base 8), opcionalmente precedido de sinal (- ou +).

 

Para usar a notação octal, você precisa preceder o número com um 0 (zero). Para utilizar a notação hexadecimal, preceda número com 0x.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Oi ..GBEST..,

 

Obrigado pelo post!

 

Eu já havia lido alguma coisa sobre a função str_pad, mas ela é mais voltada para a exibição do valor, no meu caso a dúvida é sobre o tratamento do próprio PHP quando ele recebe uma variável que possui zeros à esquerda.

 

De qualquer forma, valeu pela dica!

 

------------- Ponto de Mesclagem --------------

 

Olá André,

 

Muito obrigado pela dica, ela me deu uma luz sobre o problema, pois vi o link que você me passou e nessa seção do manual do PHP ele informa que trata os números começados com zero como octais (quando começa com zero) ou como hexadecimais (quando começa com 0x). Só não entendi ainda o motivo do print exibir zero no código que passei acima.

 

Nos testes que fiz aqui, me surgiu outra dúvida, olhem só esse código:

 

<?php

$numero = 008;

switch ($numero)
{
   case ($numero > 010):
   print ("É maior <br>");
   break;
}

if($numero > 010)
   print ("É maior");
else
   print ("Não é maior");

?>

No switch o PHP informa que a variável $número é maior, mas no if informa que não é maior. Notem que a condicional é a mesma.

 

Qualquer comentário útil sobre o print do primeiro código que postei dar zero e sobre os resultados diferentes acima, serão bem vindas!

 

Um abraço!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Se você tratar esses valores como INTEIROS, o PHP vai interpretar eles como sendo do sistema octal. Uma maneira para "contornar" isso é tratar esses valores como STRINGS (porém qualquer condição lógica envolvendo os operadores de maior (>) ou menor (<) e entre outros, o PHP irá fazer o cast para um valor numérico novamente).

 

var_dump( 008 ); // int(0)
var_dump( '008' ); // string(3) "008"

 

Veja a diferença dos resultados.

 

Rodando o código acima em dois servidores diferentes, o print exibiu 0 ao invés de 8.

Isso acontece porque o octal 008 não existe ;).

Compartilhar este post


Link para o post
Compartilhar em outros sites

Oi André,

 

Para tornar a solução mais confiável eu fiz um tratamento para remover o zero à esquerda. Notei que quando a variável com zero à esquerda vem de um formulário via POST, o erro não acontece, isso porque como você falou, ele faz um cast e converte corretamente a variável.

 

Sobre a questão de mostrar 0 ao invés de 8, realmente o 8 não existe no sistema octal, pois ele vai de 0 a 7, mas confesso que não fiquei satisfeito com a solução do PHP, esse pequeno detalhe pode gerar bugs terríveis, seria mais confiável se ele apresentasse um erro ou um aviso para alertar o desenvolvedor. Bom, mas isso é minha opinião, essa vai entrar para a minha lista de pegadinhas :D

 

Valeu!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Notei que quando a variável com zero à esquerda vem de um formulário via POST, o erro não acontece, isso porque como você falou, ele faz um cast e converte corretamente a variável.

Pra te falar a verdade não é bem isso. O que aconteçe é que TODO valor que chega ao PHP por alguma entrada (GET, POST e etc), ele chega como uma STRING. Independende do valor ser apenas números (um inteiro por exemplo) esse valor será interpretado como uma string.

 

Por isso é que o erro não aconteçe nessa situação, pois acontece justamente o que eu citei nos posts acima.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom amigo, na base octal, o maior dígito é 7, do mesmo modo que a base decimal é 9...

 

Logo, 008 NÃO existe em base octal, tal como 2 não existe em base binária, etc...

 

Minha sugestão é:

Faça o casting para um número decimal e guarde em outra variável, faça as comaprações que tiver que fazer e depois insira no banco o valor com os 0's

Compartilhar este post


Link para o post
Compartilhar em outros sites

Oi André,

 

É verdade, foi o que eu quis dizer na citação que você destacou, ou seja, vindo via POST, GET ou etc. o PHP trata corretamente a variável quando eu a utilizo para comparar com um inteiro. Isso porque ele primeiramente a enxerga como uma string, mas quando comparada com um inteiro usando < (menor que) ou > (maior que) por exemplo, ele automaticamente a trata como um inteiro também.

 

Acredito que agora tenha ficado bastante clara essa questão que é importante para todo desenvolvedor.

 

Um abraço!

 

 

Notei que quando a variável com zero à esquerda vem de um formulário via POST, o erro não acontece, isso porque como você falou, ele faz um cast e converte corretamente a variável.

Pra te falar a verdade não é bem isso. O que aconteçe é que TODO valor que chega ao PHP por alguma entrada (GET, POST e etc), ele chega como uma STRING. Independende do valor ser apenas números (um inteiro por exemplo) esse valor será interpretado como uma string.

 

Por isso é que o erro não aconteçe nessa situação, pois acontece justamente o que eu citei nos posts acima.

 

Olá Rick,

 

Sobre o 8 não existir na base octal, você tem razão, mas a questão que quis levantar não foi essa, vou colar abaixo o comentário que fiz no post mais acima:

 

"Sobre a questão de mostrar 0 ao invés de 8, realmente o 8 não existe no sistema octal, pois ele vai de 0 a 7, mas confesso que não fiquei satisfeito com a solução do PHP, esse pequeno detalhe pode gerar bugs terríveis, seria mais confiável se ele apresentasse um erro ou um aviso para alertar o desenvolvedor. Bom, mas isso é minha opinião, essa vai entrar para a minha lista de pegadinhas :D "

 

Reforçando o que falei acima, minha crítica é sobre o retorno que o PHP nos dá, pois se 008 não existe na base octal o correto seria o PHP apresentar um erro ou um aviso, porque da forma que ele está tratando a situação é como se 008 fosse igual a 0, mas todos sabemos que isso não é verdade.

 

Sobre a solução na minha aplicação, eu fiz um tratamento removendo os zeros à esquerda para evitar qualquer erro inesperado, fiz vários testes e agora estou confiante no resultado.

 

Agradeço pela sua dica!

 

Um abraço!

 

 

 

Bom amigo, na base octal, o maior dígito é 7, do mesmo modo que a base decimal é 9...

 

Logo, 008 NÃO existe em base octal, tal como 2 não existe em base binária, etc...

 

Minha sugestão é:

Faça o casting para um número decimal e guarde em outra variável, faça as comaprações que tiver que fazer e depois insira no banco o valor com os 0's

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.