2011-12-13 1 views
1

Je suis confronté à un problème étrange avec PHP. Cet exemple simple:

<?php 
$array = array(
    'zero', 
    'one', 
    'id' => 'two' 
); 

foreach ($array as $key => $value) { 
    if ($key == "id") { 
    echo "Key: ". $key .", value: ". $value ."\n"; 
    } 
} 
?> 

devrait (AMHA) Sortie ceci:

Key: id, value: two 

Mais il sort

Key: 0, value: zero 
Key: id, value: two 

Comment est-ce possible: 0 == "id"?

+0

L'avez-vous essayé avec une comparaison stricte ('===')? – jprofitt

+0

Il devrait vous donner "Key: 0, value: zero ..." cependant, est-ce une faute de frappe là-bas? http://codepad.org/qGfe1jNC. –

+0

Typo Yeap, je le corrige en ce moment. –

Répondre

6

Lorsque $ clé est 0 et obtient par rapport à la chaîne "id", la chaîne ("id") sera converti en un entier. Depuis "id" ne peut pas être transformé en nombre entier valide que la conversion donnera 0 et l'instruction if devient true.

Puisque vous ne voulez pas que la conversion implicite se produise entre deux types qui ne sont pas compatibles, utilisez la version === plus stricte de ==. === verra si les variables sont du même type et ont la même valeur exacte.

if ($key === "id") { 
    ... 
} 

Documentation PHP: Comparison Operators


Exemples

var_dump (0   == (int)"id"); 
var_dump ((string)0 == "id"); 
var_dump (0  === "id"); 

var_dump (1.0 === 1); 

sortie

bool(true) 
bool(false) 
bool(false) 
bool(false) # be careful! 
3

Vous êtes mordu par un processus appelé type juggling.

les opérations suivantes:

var_dump(0 == "id"); 

Il sortira bool(true).

PHP effectue une comparaison d'entier, et quand il tente de convertir la chaîne "id" en nombre entier, le résultat est 0. PHP analysera heureusement les premiers chiffres d'une chaîne et s'arrêtera à la première valeur non numérique, ce qui donnera l'entier 123 pour les chaînes comme "123xyz". Parce qu'il n'y a aucun chiffre principal dans la chaîne "id", il est analysé comme nombre entier 0.

La solution est d'utiliser ===, qui compare la valeur et du type de deux variables, sans tenter de jongler les types des opérandes.

-1

Si vous définissez l'expression logique de prendre en compte vartype

if (key === "id") 

si fonctionnera. Tout comme @refp dit.

+0

Comme le -1 sans explication. Très éducatif – Alfabravo

+1

Bien que je ne sois pas le downvoter, je ne comprends pas pourquoi vous postez une réponse pour indiquer une autre bonne réponse. Votre message aurait dû être un commentaire, ce qui pourrait être une raison probable de la baisse. – Repox

+0

@Repox simple: l'autre bonne réponse était plus courte avant d'être éditée. Donc, j'ai un peu mis le mien pour le compléter. A partir de maintenant, je vais encapsuler mes réponses hehehe. – Alfabravo

0

Ce:

$key == 'id' 

... fera PHP faire rapport entier, puisque le lvalue est un entier.

Si vous vous demandez pourquoi ceci:

if ($key) { ... } 

... ne donnerait pas le même résultat, bien qu'il est parce que les lvalue ici (tout omis) est booléenne, ce qui équivaut à:

if (true == $key) { ... } 

Par conséquent, PHP va tenter une comparaison booléenne. Vous pouvez utiliser l'opérateur === pour forcer une vérification de type. Vous pouvez vous référer aux codes Type Comparison Tables et Comparison Operators Table.

Questions connexes