Странное сравнение $ key => $ value с PHP - PullRequest
1 голос
/ 14 декабря 2011

У меня странная проблема с PHP. Этот простой пример:

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

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

должен (imho) вывести это:

Key: id, value: two

Но выводит

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

Как это возможно: 0 == "id"?

Ответы [ 4 ]

6 голосов
/ 14 декабря 2011

Когда $ key равен 0 и сравнивается со строкой " id ", строка (" id ") будет преобразована в целое число. Поскольку " id " не может быть преобразовано в действительное целое число, преобразование даст 0, и оператор if станет истинным.

Поскольку вы не хотите, чтобы неявное преобразование происходило между двумя несовместимыми типами, используйте более строгую === версию ==. === увидит, имеют ли переменные одинаковый тип и одинаковое ли точное значение.

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

Документация PHP: операторы сравнения


Примеры

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

var_dump (1.0 === 1);

выход

bool(true)
bool(false)
bool(false)
bool(false) # be careful!
3 голосов
/ 14 декабря 2011

Вас укусил процесс, называемый type juggling .

Попробуйте следующее:

var_dump(0 == "id");

Будет выведено bool(true).

PHP выполняет целочисленное сравнение, и когда он пытается преобразовать строку "id" в целое число, результатом будет 0.PHP с радостью проанализирует первые цифры строки и остановится на первом нечисловом значении, получив целое число 123 для таких строк, как «123xyz».Поскольку в строке "id" нет начальных цифр, она анализируется как целое число 0.

. Решение заключается в использовании ===, который сравнивает значения и типадве переменные, не пытаясь манипулировать типами операндов.

0 голосов
/ 14 декабря 2011

This:

$key == 'id'

... заставит PHP выполнить целочисленное сравнение, поскольку lvalue является целым числом.

Если вам интересно, почему это:

if ($key) { ... }

... не дал бы того же результата, но это потому, что lvalue здесь (хотя и опущен) является логическим, эквивалентным:

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

Следовательно, PHP попытается выполнить логическое сравнение.Вы можете использовать оператор === для принудительной проверки типа.

Вы можете обратиться к таблицам сравнения типов и к таблице операторов сравнения .

0 голосов
/ 14 декабря 2011

Если вы установите логическое выражение для учета типа vartype

if (key === "id")

если будет работать. Как говорит @refp.

...