【问题标题】:Why does PHP 8 treat 42 == " 42" as true?为什么 PHP 8 将 42 == " 42" 视为真?
【发布时间】:2021-03-10 10:36:25
【问题描述】:

PHP 8 已经发布。它对相等运算符的行为进行了更改。根据the documentation,这就是它现在的行为方式:

数字和非数字字符串之间的非严格比较现在通过将数字转换为字符串并比较字符串来工作。

但是,在 PHP 8 和 PHP 的早期版本中,此表达式的计算结果均为 true:

42 == " 42" // true

这对我来说没有意义。根据文档,数字应该转换为字符串"42",这肯定不等于字符串" 42",对吧?

【问题讨论】:

标签: php php-8


【解决方案1】:

您引用的文档实际上是正确的,但可能会更清楚:

数字和非数字字符串之间的非严格比较现在通过将数字转换为字符串并比较字符串来工作。

我已将关键短语“非数字字符串”加粗。

在 PHP 的各个部分中,“数字字符串”的概念是一种伪类型:任何 看起来像数字的字符串都可以被视为语言。这是为了帮助 PHP 的主要用例从 Web 请求中获取数据(始终是字符串)并在操作中使用它(可能希望将其视为数字)。

其中一个发挥作用的地方是 == 运算符,它试图“聪明”地了解您要比较的内容。

如果 PHP 确定 == 运算符的两边都是数字 数字字符串,它将通过将它们都转换为整数(或浮点数,如果合适)来执行比较,并查看是否它们具有相同的 numeric 值。 “数字字符串”的定义非常广泛,并且允许使用前导空格;从 PHP 8 开始,它现在还允许尾随空格,以保持一致性。

所以在你的例子中," 42" 是一个“数字字符串”,42 是一个实际数字,所以执行的比较是(int)" 42" === 42

您的报价中描述的更改是针对一侧是实际数字(整数或浮点数)而另一侧是 非数字 字符串的情况,这是 PHP 所具有的决定“看起来不像一个数字”。在旧版本的 PHP 中,这转换为 int,因此"hello" == 0 将评估(int)"hello" === 0,即true。在 PHP 8 中,this case 转换为字符串,因此"hello" == 0 将评估"hello" === (string)0,即false

【讨论】:

    【解决方案2】:

    简答:

    在 PHP 8 和 PHP 7 中,42 == " 42" 为真,在 PHP 7 和 PHP 8 中,"42" == " 42" 为真。

    长答案:

    我认为您对相等运算符== 在 PHP 中的工作方式存在误解。在 PHP 8 和早期版本的 PHP 中,相等运算符处理看起来是数字的字符串与其他字符串不同:

    <?php
    // the == operator does type juggling and also handles numerical strings differently:
    var_export("42" == "42"); // true
    var_export(42 == "42"); // true
    var_export("42" == " 42"); // true
    var_export("42" == "42 "); // false in PHP 7 and true in PHP 8
    var_export("42" == "042"); // true
    var_export("10" == "1e1"); // true
    var_export("abc" == " abc"); // false
    var_export("42" == "abc 42"); // false
    
    echo "\n";
    
    // the === operator does not do type juggling and does not handle numerical strings differently:
    var_export("42" === "42"); // true
    var_export(42 === "42"); // false
    var_export("42" === " 42"); // false
    var_export("42" === "42 "); // false
    var_export("42" === "042"); // false
    var_export("10" === "1e1"); // false
    var_export("abc" === " abc"); // false
    var_export("42" === "abc 42"); // false
    
    echo "\n";
    
    

    即使在 PHP 8 中,== 运算符也会进行类型处理,而且它处理数字字符串的方式也不同。这个原则没有改变。 PHP 8 的变化是:

    • 相等运算符 == 在 PHP 8 和 PHP 7 中的行为不同,用于比较数字和非数字字符串
    • PHP 8 中将哪些字符串视为数字字符串有所不同

    关于后一点,请阅读:

    [在 PHP 8 中] 对数字字符串的处理进行了更改,使其更加直观且不易出错。现在允许在数字字符串中使用尾随空格,以便与前导空格的处理方式保持一致。这主要影响:

    • is_numeric() 函数
    • 字符串到字符串的比较
    • 类型声明
    • 递增和递减操作

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-09
      • 1970-01-01
      • 2011-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多