#php #arrays
Вопрос:
Я действительно не понимаю, почему эта операция работает. Кто-нибудь может это объяснить?
$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 это не должно было сработать.
Правка: Вычеркните это, по-видимому, в нем упоминается, что свободные сравнения между строкой и 0 верны. Но я все еще не знаю, почему.
Правка 2: Я пересмотрел свой вопрос, почему $test2
ценность "3581169b064f71be1630b321d3ca318f"
не работает?
Комментарии:
1. какое значение $test не работает?
2. Если вы запустите код, он будет выводить только
Test 1 is Equal!?
3. Редактировать 2 : потому что оператор сравнения автоматически приводит «3581169b064f71be1630b321d3ca318f» и, поскольку он начинается с чисел, он преобразуется в int и получает первую часть строки до буквы в качестве значения. и это сравнение (3581169 == 0) с ложным
4. FWIW, распечатка значений
$test1 0
и$test2 0
дала бы ключ к пониманию того, что происходит. Или, альтернативно, значения$test1
и$test2
(с использованием оператора идентификации).
Ответ №1:
Преобразование строк в числа
Когда строка оценивается в числовом контексте, результирующее значение и тип определяются следующим образом.
Строка будет оценена как плавающая, если она содержит какой-либо из символов».», » е » или «Е». В противном случае он будет оцениваться как целое число.
Значение задается начальной частью строки. Если строка начинается с допустимых числовых данных, это будет используемое значение. В противном случае значение будет равно 0 (нулю). Допустимые числовые данные-это необязательный знак, за которым следует одна или несколько цифр (необязательно содержащих десятичную точку), за которыми следует необязательный показатель степени. Показатель степени представляет собой букву » е » или «Е», за которой следует одна или несколько цифр.
Комментарии:
1. Все еще не думаю, что он должен преобразовываться в 0 или, по крайней мере, если он начинается с числа, не преобразовываться в десятичное число, если в строке есть ошибочные символы.
2. PHP не имеет типа «NaN», такого как Javascript (другой язык с произвольной типизацией), поэтому он в значительной степени должен быть преобразован в 0, так как другого способа не было бы (преобразование в NULL не сработало бы, потому что NULL также преобразуется в 0). Я думаю, что ответ заключается не в том, чтобы использовать свободное сравнение ( = = ) или сначала проверять строку.
3. В дополнение к этому ответу , при сравнении 2 элементов с
==
оператором , он преобразуется в общий тип. об этом говорится здесь. php.net/manual/en/language.operators.comparison.php4. Лучший способ провести тест-использовать «пустой» метод:
empty($test1)
5. @Pascal_dher — тьфу, нет. Причина: скажи, что ты имеешь в виду . Здесь цель состоит в том, чтобы задать вопрос «Равно ли это значение 0» . Выражение, похожее на намерение, очевидно , в то время как выражение, основанное на причудах языка, неочевидно . ИМХО. [Если бы единственным существующим компьютерным языком был PHP, то ваше предложение было бы разумным. Однако это все равно не сделало бы его лучшим способом; это просто сделало бы его эквивалентно хорошей альтернативой .]
Ответ №2:
Преобразование типов с помощью оператора ==
Оператор == представляет собой слабо типизированное сравнение. Он преобразует оба в общий тип и сравнивает их. Здесь объясняется, как строки преобразуются в целые числа.
Обратите внимание, что страница, на которую вы ссылаетесь, не противоречит этому. Проверьте вторую таблицу, где говорится, что сравнение целого 0
числа со строкой "php"
с использованием ==
должно быть истинным.
Что происходит, так это то, что строка преобразуется в целое число, а нечисловые строки (строки, которые не содержат числа или начинаются с него) преобразуются в 0
.
Числовые и нечисловые строки
Строка, состоящая из числа или начинающаяся с числа, считается числовой строкой. Если в строке после этого числа есть другие символы, они игнорируются.
Если строка начинается с символа, который нельзя интерпретировать как часть числа, то она является нечисловой строкой и преобразуется в 0
. Это не означает, что числовая строка должна начинаться с цифры (0-9) — например "-1"
, это числовая строка, потому что в этом случае знак минус является частью числа.
Так, например, ваша строка "d85d1d81b25614a3504a3d5601a9cb2e"
не начинается с числа, поэтому она преобразуется в 0
. Но ваша вторая строка "3581169b064f71be1630b321d3ca318f"
будет преобразована в целое 3581169
число . Так вот почему ваш второй тест работает по-другому.
Что вам следует делать
Вы, наверное, хотите:
if ($test1 === "0")
Обратите внимание на использование тройных равных вместо двойных равных. Это гарантирует, что вы сравниваете строку, содержащую только нулевую цифру, и предотвращает любое преобразование типов.
Ответ №3:
После некоторого расследования выяснилось, что Эйдан из руководства по PHP упоминал, что любые строки, которые не начинаются с числа, будут преобразованы в 0 при приведении в виде целого числа.
Это означает, что:
("php" == 0) === true
("1php" == 0) === false
Очень раздражает и плохо документирован. Это было внизу комментариев на странице сравнения типов.
Комментарии:
1. Да, я так и понял, что это все. Действительно, плохая документация.
2. Я вовсе не думаю, что это плохая документация. Неявное преобразование типов является основой PHP, что очень хорошо объясняется в руководстве в разделе о типах, особенно в разделе «Манипулирование типами». == — это слабо типизированное сравнение; использование === вместо этого может помочь предотвратить запутанные ситуации.
3. См. Также «Преобразование строк в числа» по адресу us3.php.net/manual/en/…
Ответ №4:
$test1 = "d85d1d81b25614a3504a3d5601a9cb2e";
эта строка начинается с «d», которое не является допустимым числом, значение var будет равно 0, и ваш тест № 1 пройдет.
$test2 = "3581169b064f71be1630b321d3ca318f";
эта строка начинается с 3581169, что является допустимым числом, поэтому значение var будет равно тому значению, которое не равно 0.
Так что ваш тест № 2 не пройдет.
Ответ №5:
Я использовал некоторые преобразования и сравнения, чтобы проверить, является ли числовая строка числом:
$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