J'ai le morceau de code suivant:
$item['price'] = 0;
/* Code to get item information goes in here */
if($item['price'] == 'e') {
$item['price'] = -1;
}
Il est destiné à initialiser le prix de l'article à 0, puis à obtenir des informations à ce sujet. Si le prix est indiqué par «e», cela signifie un échange au lieu d'une vente, qui est stocké dans une base de données sous la forme d'un nombre négatif.
Il est également possible de laisser le prix à 0, soit parce que l'objet est un bonus, soit parce que le prix sera fixé ultérieurement.
Mais, chaque fois que le prix n'est pas défini, ce qui lui laisse la valeur initiale de 0, la if
boucle indiquée ci-dessus est évaluée comme vraie et le prix est défini sur -1. Autrement dit, il considère 0 comme égal à «e».
Comment cela peut-il être expliqué?
Lorsque le prix est fourni à 0 (après l'initialisation), le comportement est erratique: parfois le if est évalué comme vrai, parfois il est évalué comme faux. *
if((string)$item['price'] == 'e')
corrige le comportement étrange. Voir stackoverflow.com/a/48912540/1579327 pour plus de détailsRéponses:
Vous faites
==
ce qui trie les types pour vous.0
est un int, donc dans ce cas, il sera converti'e'
en un int. Ce qui n'est pas analysable en tant que tel et deviendra0
. Une chaîne'0e'
deviendrait0
et correspondrait!Utilisation
===
la source
Cela est dû à la façon dont PHP effectue l'opération de comparaison que l'
==
opérateur de comparaison désigne:Comme le premier opérande est un nombre (
0
) et le second une chaîne ('e'
), la chaîne est également convertie en nombre (voir aussi le tableau Comparaison avec divers types ). La page de manuel sur le type de données chaîne définit la façon dont la conversion chaîne en nombre est effectuée:Dans ce cas, la chaîne est
'e'
et donc elle sera évaluée comme un flottant:Comme
'e'
ne commence pas avec des données numériques valides, il est évalué comme flottant0
.la source
évalue
true
parce que d' abord"ABC"
est converti en entier et devient0
ensuite comparé à0
.C'est un comportement étrange du langage PHP: normalement, on s'attend
0
à être promu en chaîne"0"
puis comparé à"ABC"
un résultatfalse
. C'est peut-être ce qui se passe dans d'autres langages comme JavaScript, où la comparaison faible est"ABC" == 0
évaluéefalse
.Faire une comparaison stricte résout le problème:
évalue
false
.Mais que faire si j'ai besoin de comparer des nombres sous forme de chaînes avec des nombres?
évalue
false
parce que les termes gauche et droit sont de type différent.Ce qui est réellement nécessaire, c'est une comparaison faible sans les pièges de la jonglerie de type PHP.
La solution est de promouvoir explicitement les termes en chaîne, puis de faire une comparaison (strict ou faible n'a plus d'importance).
est
true
tandis que
est
false
Appliqué au code d'origine:
la source
L'opérateur == essaiera de faire correspondre les valeurs même si elles sont de types différents. Par exemple:
Si vous avez également besoin d'une comparaison de type, utilisez l'opérateur ===:
la source
Votre problème est l'opérateur double égal, qui transtypera le membre de droite dans le type de gauche. Utilisez strict si vous préférez.
Revenons à votre code (copié ci-dessus). Dans ce cas, dans la plupart des cas, $ item ['price'] est un entier (sauf quand il est égal à e, évidemment). En tant que tel, selon les lois de PHP, PHP sera converti
"e"
en nombre entier, ce qui donneint(0)
. (Ne me croyez pas?<?php $i="e"; echo (int)$i; ?>
).Pour vous en sortir facilement, utilisez l'opérateur triple égal (comparaison exacte), qui vérifiera le type et ne sera pas implicitement typé.
PS: un fait amusant PHP:
a == b
cela n'implique pas celab == a
. Prenez votre exemple et inversez-le:if ("e" == $item['price'])
ne sera jamais réellement rempli à condition que $ item ['price'] soit toujours un entier.la source
Il existe une méthode assez pratique en PHP pour valider un mélange de «0», «false», «off» comme == false et «1», «on», «true» comme == true, ce qui est souvent négligé. C'est particulièrement utile pour analyser les arguments GET / POST:
Ce n'est pas tout à fait pertinent pour ce cas d'utilisation, mais étant donné la similitude et le fait que c'est le résultat, la recherche a tendance à trouver en posant la question de valider (chaîne) "0" comme faux, je pensais que cela aiderait les autres.
http://www.php.net/manual/en/filter.filters.validate.php
la source
Vous devez utiliser à la
===
place de==
, car l'opérateur ordinaire ne compare pas les types. Au lieu de cela, il tentera de transtyper les éléments.Pendant ce temps, le
===
prend en considération le type d'éléments.===
signifie "égal",==
signifie "eeeeh .. un peu ressemble à"la source
if((string)$item['price']=='e'){ $item['price'] = -1; }
===
opérateurJe pense qu'il est préférable de montrer par des exemples que j'ai faits, tout en rencontrant le même comportement étrange. Voir mon cas de test et j'espère qu'il vous aidera à mieux comprendre le comportement:
la source
En gros, utilisez toujours l'
===
opérateur pour garantir la sécurité du type.la source