php 将字符串与整数进行比较会产生奇怪的结果

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/672040/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 23:26:21  来源:igfitidea点击:

Comparing String to Integer gives strange results

phpcastingcomparison

提问by St. John Johnson

I'm really confused as to why this operation works. Can someone explain it?

我真的很困惑为什么这个操作有效。有人可以解释一下吗?

$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!?

For clarification, I am trying to compare the string "0"to the $testvariables. I already know to fix the code I can just enclose (as I should have) the 0in ""s

为了澄清起见,我试图将字符串"0"$test变量进行比较。我已经知道修复代码我可以附上(我应该有)0in ""s

I'm wondering if this is a PHP bug, a server bug, or somehow a valid operation. According to http://us3.php.net/types.comparisonsthis should nothave worked.

我想知道这是 PHP 错误、服务器错误还是某种有效操作。根据http://us3.php.net/types.comparisons应该起作用。

Edit:Scratch that, apparently it does mention that Loose comparisons between string and 0 is true. But I still don't know why.

编辑:从头开始,显然它确实提到字符串和 0 之间的松散比较是正确的。但我仍然不知道为什么。

Edit 2:I've revised my question, why does the $test2value of "3581169b064f71be1630b321d3ca318f"not work?

编辑 2:我修改了我的问题,为什么$test2"3581169b064f71be1630b321d3ca318f"不起作用?

回答by Assaf Lavie

From the PHP manual:

从 PHP 手册

String conversion to numbers

When a string is evaluated in a numeric context, the resulting value and type are determined as follows.

The string will be evaluated as a float if it contains any of the characters '.', 'e', or 'E'. Otherwise, it will be evaluated as an integer.

The value is given by the initial portion of the string. If the string starts with valid numeric data, this will be the value used. Otherwise, the value will be 0 (zero). Valid numeric data is an optional sign, followed by one or more digits (optionally containing a decimal point), followed by an optional exponent. The exponent is an 'e' or 'E' followed by one or more digits.

字符串转换为数字

当在数字上下文中计算字符串时,结果值和类型按如下方式确定。

如果字符串包含任何字符“.”、“e”或“E”,则该字符串将被评估为浮点数。否则,它将被评估为整数。

该值由字符串的初始部分给出。如果字符串以有效的数字数据开头,这将是使用的值。否则,该值将为 0(零)。有效的数字数据是一个可选的符号,后跟一个或多个数字(可选地包含小数点),后跟一个可选的指数。指数是“e”或“E”后跟一位或多位数字。

回答by thomasrutter

Type conversion using the == operator

使用 == 运算符进行类型转换

The == operator is a loosely-typed comparison. It will convert both to a common type and compare them. The way strings are converted to integers is explained here.

== 运算符是一种松散类型的比较。它将两者都转换为通用类型并比较它们。将字符串转换为整数的方式在此处进行了说明

Note that the page you linked todoesn't contradict this. Check the second table, where it says that comparing the integer 0to a string "php"using ==shall be true.

请注意,您链接到页面与此并不矛盾。检查第二个表,它说将整数0与字符串"php"进行比较使用==应为真。

What happens is that the string is converted to integer, and non-numeric strings (strings that do not contain or begin with a number) convert to 0.

发生的情况是字符串转换为整数,非数字字符串(不包含或以数字开头的字符串)转换为0.

Numeric vs non-numeric strings

数字与非数字字符串

A string that consists of a number, or begins with a number, is considered a numeric string. If the string has other characters after that number, these are ignored.

由数字组成或以数字开头的字符串被视为数字字符串。如果字符串在该数字之后有其他字符,则忽略这些字符。

If a string starts with a character that cannot be interpreted as part of a number, then it is a non-numeric stringand will convert to 0. This doesn't mean that a numeric string has to start with a digit (0-9) - for example "-1"is a numeric string because the minus sign is part of a number in that case.

如果字符串以无法解释为数字的一部分的字符开头,则它是非数字字符串并将转换为0. 这并不意味着数字字符串必须以数字 (0-9) 开头 - 例如"-1"是数字字符串,因为在这种情况下减号是数字的一部分。

So for example, your string "d85d1d81b25614a3504a3d5601a9cb2e"does not start with a number, so it would convert to 0. But your second string "3581169b064f71be1630b321d3ca318f"would be converted to integer 3581169. So that's why your second test does not work the same way.

例如,您的字符串"d85d1d81b25614a3504a3d5601a9cb2e"不以数字开头,因此它会转换为0. 但是您的第二个字符串"3581169b064f71be1630b321d3ca318f"将转换为 integer 3581169。所以这就是为什么你的第二个测试不能以同样的方式工作。

What you should do

你应该做什么

You probably want:

你可能想要:

if ($test1 === "0")

Notice the use of triple equals instead of a double equals. This ensures that what you are comparing is a string that contains the digit zero only, and prevents any type conversion.

注意使用三等号而不是双等号。这确保您比较的是一个仅包含数字零的字符串,并防止任何类型转换。

回答by St. John Johnson

After some investigation, it turns out aidan from the PHP manual mentioned that any strings that do not start with a numberwill be converted to 0 when casted as an integer.

经过一番调查,结果发现 PHP 手册中的 aidan 提到任何不以数字开头的字符串在转换为整数时都将转换为 0。

This means that:

这意味着:

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

Very annoying and not well documented. It was at the bottom of the comments on the type comparison page.

非常烦人,而且没有很好的记录。它位于类型比较页面的评论底部。

回答by HBR

$test1 = "d85d1d81b25614a3504a3d5601a9cb2e";

this string starts with a "d", which is not valid number, the var will resolve to 0 and your test#1 will pass.

此字符串以“d”开头,它不是有效数字,var 将解析为 0,您的 test#1 将通过。

$test2 = "3581169b064f71be1630b321d3ca318f";

this string starts with 3581169 which is a valid number, so the var will resolve to that value which is not equal to 0. So your test#2 will not pass.

此字符串以 3581169 开头,这是一个有效数字,因此 var 将解析为不等于 0 的值。因此您的 test#2 将不会通过。

回答by Eiad Samman

I've been using some conversions and comparisons to test if a numeric stringis a number:

我一直在使用一些转换和比较来测试数字字符串是否为数字:

$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