PHP 8 上大于或小于比较的意外结果
Unexpected result of greater than or less than comparison on PHP 8
下面的 returns false
在 PHP 7 但 true
在 PHP 8。有人可以解释为什么会这样吗?
var_dump("U0M262" > 100000);
字符串和数字的比较没有明显正确的结果。在许多语言中,它只会给出一个错误;在其他情况下,包括 PHP,该语言试图通过将两个操作数转换为同一类型来理解它,但这涉及判断“更喜欢”哪种类型。
从历史上看,PHP 更喜欢比较数字而不是比较字符串:它将 "U0M262" > 100000
视为 (int)"U0M262" > 100000
。由于(int)"U0M262"
没有明显的值,所以求值为0
,表达式变为0 > 100000
,为false。
从 PHP 8 开始,this behaviour has changed 和 PHP 现在只对“数字字符串”使用数字比较,例如"42"
显然“看起来像” 42
.
由于 "U0M262"
不符合数字字符串的要求,"U0M262" > 100000
现在被视为 "U0M262" > (string)100000
。这会对两个字符串的排序顺序进行字节比较,并发现由于“U”在 ASCII 中出现在“1”之后(以及任何 ASCII 派生编码,包括 UTF -8),结果为真。
由于ASCII(以及UTF-8等兼容编码)的排列方式:
- 以控制字符或 space 开头的字符串将“小于”任何数字
- 以字母开头的字符串将“多于”任何数字
- 以任何“!”开头的字符串 # $ % & ' ( ) * + , - 。 /”将“小于”任何数字
- 对于以数字开头的字符串,需要查看各个字节
- 任何其他字符串将“大于”任何数字
与以往一样,您可以告诉 PHP 您想要进行哪种比较,并使用显式转换在所有版本中获得正确的行为:
var_dump((int)"U0M262" > (int)100000); // bool(false)
var_dump((string)"U0M262" > (string)100000); // bool(true)
(显然,如果您对双方都进行硬编码,这毫无意义,但假设其中一方或双方都是变量,这就是您的做法。)
下面的 returns false
在 PHP 7 但 true
在 PHP 8。有人可以解释为什么会这样吗?
var_dump("U0M262" > 100000);
字符串和数字的比较没有明显正确的结果。在许多语言中,它只会给出一个错误;在其他情况下,包括 PHP,该语言试图通过将两个操作数转换为同一类型来理解它,但这涉及判断“更喜欢”哪种类型。
从历史上看,PHP 更喜欢比较数字而不是比较字符串:它将 "U0M262" > 100000
视为 (int)"U0M262" > 100000
。由于(int)"U0M262"
没有明显的值,所以求值为0
,表达式变为0 > 100000
,为false。
从 PHP 8 开始,this behaviour has changed 和 PHP 现在只对“数字字符串”使用数字比较,例如"42"
显然“看起来像” 42
.
由于 "U0M262"
不符合数字字符串的要求,"U0M262" > 100000
现在被视为 "U0M262" > (string)100000
。这会对两个字符串的排序顺序进行字节比较,并发现由于“U”在 ASCII 中出现在“1”之后(以及任何 ASCII 派生编码,包括 UTF -8),结果为真。
由于ASCII(以及UTF-8等兼容编码)的排列方式:
- 以控制字符或 space 开头的字符串将“小于”任何数字
- 以字母开头的字符串将“多于”任何数字
- 以任何“!”开头的字符串 # $ % & ' ( ) * + , - 。 /”将“小于”任何数字
- 对于以数字开头的字符串,需要查看各个字节
- 任何其他字符串将“大于”任何数字
与以往一样,您可以告诉 PHP 您想要进行哪种比较,并使用显式转换在所有版本中获得正确的行为:
var_dump((int)"U0M262" > (int)100000); // bool(false)
var_dump((string)"U0M262" > (string)100000); // bool(true)
(显然,如果您对双方都进行硬编码,这毫无意义,但假设其中一方或双方都是变量,这就是您的做法。)