Сравнение строки с целым числом дает странные результаты - PullRequest
29 голосов
/ 23 марта 2009

Я действительно не понимаю, почему эта операция работает. Может кто-нибудь объяснить это?

$test1 = "d85d1d81b25614a3504a3d5601a9cb2e";
$test2 = "3581169b064f71be1630b321d3ca318f";

if ($test1 == 0)
  echo "Test 1 is Equal!?";
if ($test2 == 0)
  echo "Test 2 is Equal!?";

// Returns: Test 1 is Equal!?

Для пояснения я пытаюсь сравнить строку "0" с переменными $test. Я уже знаю, чтобы исправить код, который я могу просто заключить (как я должен был) 0 в "" s

Мне интересно, является ли это ошибкой PHP, ошибкой сервера или какой-либо допустимой операцией. Согласно http://us3.php.net/types.comparisons этот не должен работать.

Редактировать: Поцарапайте, что, очевидно, он упоминает, что Loose сравнения между строкой и 0 является правдой. Но я до сих пор не знаю, почему.

Редактировать 2: Я пересмотрел свой вопрос, почему не работает $test2 значение "3581169b064f71be1630b321d3ca318f"?

Ответы [ 5 ]

36 голосов
/ 23 марта 2009

Из руководства по PHP :

Преобразование строки в числа

Когда строка оценивается в числовой контекст, результирующее значение и тип определяются следующим образом.

Строка будет оценена как плавать, если он содержит какой-либо из символы '.', 'e' или 'E'. В противном случае он будет оцениваться как целое число.

Значение дается начальным часть строки. Если строка начинается с действительных числовых данных, это будет используемое значение. В противном случае значение будет 0 (ноль). Действительный числовой данные - необязательный знак, сопровождаемый одна или несколько цифр (опционально с десятичной точкой), а затем по дополнительному показателю. Экспонента это «е» или «е», за которым следует один или больше цифр.

9 голосов
/ 23 марта 2009

Преобразование типов с помощью оператора ==

Оператор == - это типизированное сравнение. Он преобразует оба в общий тип и сравнивает их. Способ преобразования строк в целые числа описан здесь .

Обратите внимание, что страница , на которую вы ссылались , не противоречит этому. Проверьте вторую таблицу, где написано, что сравнение целого числа 0 со строкой "php" с использованием == должно быть истинным.

В результате получается, что строка преобразуется в целое число, а нечисловые строки (строки, которые не содержат или начинаются с числа) преобразуются в 0.

Числовые и нечисловые строки

Строка, которая состоит из числа или начинается с числа, считается числовой строкой . Если в строке есть другие символы после этого числа, они игнорируются.

Если строка начинается с символа, который нельзя интерпретировать как часть числа, то это нечисловая строка и преобразуется в 0. Это не означает, что числовая строка должна начинаться с цифры (0-9) - например, "-1" является числовой строкой, поскольку знак минус в этом случае является частью числа.

Так, например, ваша строка "d85d1d81b25614a3504a3d5601a9cb2e" не начинается с числа, поэтому она будет преобразована в 0. Но ваша вторая строка "3581169b064f71be1630b321d3ca318f" будет преобразована в целое число 3581169. Вот почему ваш второй тест не работает так же.

Что делать

Вы, вероятно, хотите:

if ($test1 === "0")

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

7 голосов
/ 23 марта 2009

После некоторого расследования из справочника PHP упоминается, что любые строки, которые не начинаются с числа , будут преобразованы в 0 при преобразовании в целое число.

Это означает, что:

("php" == 0) === true
("1php" == 0) === false

Очень раздражает и плохо документируется. Это было внизу комментариев на странице сравнения типов.

2 голосов
/ 06 августа 2014
$test1 = "d85d1d81b25614a3504a3d5601a9cb2e";

эта строка начинается с "d", что является недопустимым числом, переменная будет преобразована в 0 и ваш тест # 1 пройдет.

$test2 = "3581169b064f71be1630b321d3ca318f";

эта строка начинается с 3581169, который является допустимым числом, поэтому переменная будет преобразована в то значение, которое не равно 0. Таким образом, ваш тест № 2 не пройдет.

1 голос
/ 06 мая 2014

Я использовал некоторые преобразования и сравнения, чтобы проверить, является ли числовая строка числом:

$test1="19de6a91d2ca9d91721d82f1bd8102b6";
   echo (float)$test1==$test1; //TRUE
   echo is_float($test1); //FALSE

   //Converting the string to float and then converting it to string and compare will do the trick 
   echo (string)((float)$test1)==(string)$test1; //FALSE


$test2="5.66";
   echo (float)$test2==$test2; //TRUE

   //Testing the numeric string using `is_float` wont give the expected result
   echo is_float($test2); //FALSE

   echo (string)((float)$test2)==(string)$test2; //TRUE
...