Eu tenho o seguinte código:
$item['price'] = 0;
/* Code to get item information goes in here */
if($item['price'] == 'e') {
$item['price'] = -1;
}
A intenção é inicializar o preço do item para 0 e, em seguida, obter informações sobre ele. Se o preço for informado como 'e', significa uma troca ao invés de uma venda, que é armazenada em um banco de dados como um número negativo.
Existe também a possibilidade de deixar o preço 0, seja porque o artigo é um bónus ou porque o preço será definido posteriormente.
Porém, sempre que o preço não for definido, o que o deixa com o valor inicial 0, o if
loop indicado acima é avaliado como verdadeiro e o preço é definido como -1. Ou seja, considera 0 igual a 'e'.
Como isso pode ser explicado?
Quando o preço é fornecido como 0 (após a inicialização), o comportamento é errático: às vezes if é avaliado como verdadeiro, às vezes é avaliado como falso. *
if((string)$item['price'] == 'e')
corrige o comportamento estranho. Consulte stackoverflow.com/a/48912540/1579327 para mais detalhesRespostas:
Você está fazendo o
==
que separa os tipos para você.0
é um int, portanto, neste caso, ele será convertido'e'
em um int. Que não é analisável como um e se tornará0
. Uma string'0e'
se tornaria0
e combinaria!Usar
===
fonte
Isso se deve à forma como o PHP faz a operação de comparação que o
==
operador de comparação denota:Como o primeiro operando é um número (
0
) e o segundo é uma string ('e'
), a string também é convertida em um número (consulte também a tabela Comparação com vários tipos ). A página manual no tipo de dados de string definiu como a conversão de string em número é feita:Neste caso, a string é
'e'
e, portanto, será avaliada como um flutuante:Como
'e'
não começa com dados numéricos válidos, ele é avaliado como flutuante0
.fonte
avalia
true
porque primeiro"ABC"
é convertido em inteiro e se torna, em0
seguida , é comparado com0
.Este é um comportamento estranho da linguagem PHP: normalmente, espera-
0
se ser promovido a string"0"
e, em seguida, comparado"ABC"
com um resultadofalse
. Talvez seja o que acontece em outras linguagens como JavaScript, onde a comparação fraca"ABC" == 0
avaliafalse
.Fazer uma comparação estrita resolve o problema:
avalia
false
.Mas e se eu precisar comparar números como strings com números?
avalia
false
porque os termos esquerdo e direito são de tipos diferentes.O que é realmente necessário é uma comparação fraca sem as armadilhas do malabarismo do tipo PHP.
A solução é promover explicitamente os termos para string e então fazer uma comparação (estrito ou fraco não importa mais).
é
true
enquanto
é
false
Aplicado ao código original:
fonte
O operador == tentará combinar os valores mesmo se forem de tipos diferentes. Por exemplo:
Se você também precisar de comparação de tipo, use o operador ===:
fonte
Seu problema é o operador de igualdade dupla, que fará o typecast do membro direito pelo tipo do membro esquerdo. Use estrito se preferir.
Vamos voltar ao seu código (copiado acima). Nesse caso, na maioria dos casos, $ item ['preço'] é um inteiro (exceto quando for igual a e, obviamente). Como tal, pelas leis do PHP, o PHP será typecast
"e"
para inteiro, que produzint(0)
. (Não acredita em mim?<?php $i="e"; echo (int)$i; ?>
).Para escapar facilmente disso, use o operador de triplo igual (comparação exata), que verificará o tipo e não implicará no typecast.
PS: um fato divertido sobre PHP:
a == b
não significa issob == a
. Pegue seu exemplo e inverta-o:if ("e" == $item['price'])
nunca será realmente cumprido desde que $ item ['preço'] seja sempre um número inteiro.fonte
Existe um método bastante útil em PHP para validar uma combinação de "0", "false", "off" como == false e "1", "on", "true" como == true que é freqüentemente esquecido. É particularmente útil para analisar argumentos GET / POST:
Não é totalmente relevante para este caso de uso, mas dada a semelhança e o fato de que este é o resultado que a pesquisa tende a encontrar ao fazer a pergunta de validar (string) "0" como falso, pensei que ajudaria outros.
http://www.php.net/manual/en/filter.filters.validate.php
fonte
Você deve usar em
===
vez de==
, porque o operador comum não compara os tipos. Em vez disso, ele tentará moldar os itens.Enquanto isso,
===
leva em consideração o tipo de itens.===
significa "igual",==
significa "eeeeh .. meio que parece"fonte
if((string)$item['price']=='e'){ $item['price'] = -1; }
===
operadorEu acho que é melhor mostrar por exemplos que eu fiz, enquanto encontrava o mesmo comportamento estranho. Veja meu caso de teste e espero que ele ajude você a entender melhor o comportamento:
fonte
Basicamente, use sempre o
===
operador, para garantir a segurança de tipo.fonte