123 votes

Pourquoi PHP envisager de 0 à être égal à une chaîne de caractères?

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 et ensuite obtenir des informations à ce sujet. Si le prix est informé que le " e " signifie un échange au lieu de vendre, ce qui est indiqué par une valeur négative parce que c'est d'être stockées dans une base de données qui nécessite une valeur numérique.

Il y a aussi la possibilité de laisser les prix de 0, soit parce que le document est un bonus ou parce que le prix sera fixé en un moment plus tard.

Mais, toujours lorsque le prix n'est pas défini, ce qui laisse à la valeur initiale de 0, si la boucle indiquée ci-dessus est évaluée comme true et le prix est fixé à -1. C'est, il considère que 0 comme égal à 'e'.

Comment cela peut-il être expliqué?

Edit: Lorsque le prix est fournie à titre 0 (après initialisation), le comportement est erratique: parfois, le si est évaluée à vrai, parfois elle est fausse (false).

129voto

Nanne Points 35880

vous font == qui trie les types pour vous.

0 est un int, donc dans ce cas, il va jeter 'e' int. Ce qui n'est pas parseable comme un seul, et deviendra 0. Une chaîne de caractères '0e' deviendrait 0, et correspond!

utiliser ===

48voto

Gumbo Points 279147

Cela est dû à la façon dont PHP l'opération de comparaison que l' == opérateur de comparaison indique:

Si vous comparez un nombre avec une ficelle ou la comparaison implique des chaînes numériques, puis chaque chaîne est convertie en un nombre et de la comparaison effectuée numériquement. [...] Le type de conversion n'a pas lieu lorsque la comparaison est - === ou !== qu'il s'agit de comparer le type ainsi que la valeur.

Comme le premier opérande est un nombre (0) et la deuxième est une chaîne de caractères ('e'), la chaîne est également converti en nombre (voir aussi le tableau de Comparaison de Divers Types). La page de manuel sur le type de données string défini comment la chaîne de conversion de numéro est fait:

Lorsqu'une chaîne est évaluée dans un contexte numérique, la valeur et le type sont déterminés comme suit.

Si la chaîne ne contient aucun des caractères '.', 'e"ou"E"et la valeur numérique s'inscrit dans type entier limites (tel que défini par PHP_INT_MAX), la chaîne sera évalué comme un entier. Dans tous les autres cas, elle sera évaluée comme un float.

Dans ce cas, la chaîne est - 'e' et donc il va être évalué comme un float:

La valeur est donnée par la première partie de la chaîne. Si la chaîne commence par valide de données numériques, ce sera la valeur utilisée. Sinon, la valeur sera 0 (zéro). Valide des données numériques est un signe optionnel, suivi par un ou plusieurs chiffres (éventuellement contenant une virgule), suivi par un exposant facultatif. L'exposant est un 'e"ou"E' suivi par un ou plusieurs chiffres.

En tant que 'e' ne démarre pas avec un valide des données numériques, il évalue à flotteur 0.

8voto

MarvinLabs Points 13401

L'opérateur == va essayer de faire correspondre les valeurs même si elles sont de différents types. Par exemple:

'0' == 0 will be true

Si vous avez besoin de type de comparaison, l'utilisation de l' === opérateur:

'0' === 0 will be false

8voto

Sébastien Renauld Points 8624

Votre problème est le double de l'égalité de l'opérateur, qui typecast le membre de droite le type de la gauche. L'utilisation stricte si vous préférez.

if($item['price']=='e'){
$item['price'] = -1;
}

Revenons à votre code (copié ci-dessus). Dans ce cas, dans la plupart des cas, $item['prix'] est un entier (sauf quand il est égal à e, bien évidemment). En tant que tel, par les lois de PHP, PHP typecast "e" entier, ce qui donne int(0). (Ne me croyez pas? <?php $i="e"; echo (int)$i; ?>).

Pour obtenir plus facilement loin de cela, utiliser le triple égal (comparaison exacte) de l'opérateur, qui va vérifier le type et ne sera pas implicitement transtypage.

P. S: PHP fait amusant: a == b ne signifie pas qu' b == a. Prenez votre exemple et à l'inverse: if ("e" == $item['price']) permettra de ne jamais être satisfait à la condition que $item['prix'] est toujours un entier.

6voto

Jim Morrison Points 721

Il y a plutôt pratique de la méthode en PHP pour la validation d'un mélange de "0", "false", "off" = = false et "1", "sur", "true" = = true qui est souvent négligé. Elle est particulièrement utile pour l'analyse GET/POST arguments:

filter_var( $item['price'], FILTER_VALIDATE_BOOLEAN );

Il n'est pas entièrement pertinente pour ce cas d'utilisation, mais compte tenu de la similitude et de fait, c'est le résultat de la recherche tend à trouver quand vous posez la question de la validation (string)"0" pour de faux j'ai pensé qu'il serait utile à d'autres.

http://www.php.net/manual/en/filter.filters.validate.php

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X