【问题标题】:Why does 1234 == '1234 test' evaluate to true? [duplicate]为什么 1234 == '1234 test' 评估为真? [复制]
【发布时间】:2012-08-22 12:46:33
【问题描述】:

可能重复:
php == vs === operator

对于我确定的人来说,这是一个简单的答案。有人能解释一下为什么这个表达式的计算结果为真吗?

(1234 == '1234 test')

【问题讨论】:

  • 因为 PHP 就是这样滚动的:就像一个方轮。
  • @alfasin:是的,我可以。问题中的比较完全没有意义,没有理由不将其视为错误,即使是为了程序员。
  • @Lusitanian:“......这种比较可能有一些合法的用例。”找一个,我敢。
  • @alfasin 但它不是 1234 == '1234'有问题(这在没有复杂原因的情况下是可以理解的);这里的问题是关于 1234 == '1234 test' (这在 JavaScript 中是错误的,乍一看更不“预期”)。

标签: php equals equality


【解决方案1】:

因为您使用的是 ==(相似性)运算符,而 PHP 将字符串强制转换为 int。

要解决它,请使用 ===(相等)运算符,它不仅检查值是否相同,还检查数据类型是否相同,因此不会考虑“123”字符串和 123 int相等。

【讨论】:

【解决方案2】:

将字符串转换为整数时,直到第一个非数字字符的任何数字字符都将成为数字。因此'1234 test' 变为1234,因为空格不是数字字符。

因此1234 == '1234 test'

如果你想强制进行字符串比较,你应该强制转换为字符串:

''.(1234) == '1234 test' // implicit
(string) 1234 == '1234 test' // explicit
strval(1234) == '1234 test' // procedural

【讨论】:

    【解决方案3】:

    双等号将告诉 php 从字符串中解析一个 int。该字符串将计算为整数 1234。使用三等号 '===' 进行精确比较。

    【讨论】:

      【解决方案4】:

      如果您将数字与字符串进行比较,或者比较涉及数字字符串,则每个字符串都将转换为数字并以数字方式进行比较

      var_dump(0 == "a"); // 0 == 0 -> true
      

      【讨论】:

        【解决方案5】:

        在 PHP(和 JavaScript -- 行为略有不同)中,比较运算符 == 的工作方式与在 C 或 Java 等强类型语言中的工作方式不同。 === 运算符具有您最可能期望的行为。下面是适用于 PHP 的两个比较运算符的细分。

        ==

        这个运算符被正式称为“平等”运算符,尽管它并不真正符合“平等”这个词的正常定义。它执行所谓的类型杂耍比较。如果两个操作数的类型不匹配(在您的示例中,1234 是一个整数,1234 test 是一个字符串),PHP 将隐式将操作数转换为彼此的类型并测试新键入的值的相等性如下所示:

        <?php
        var_dump( (int) 'hi' ); // int(0)
        var_dump( (string) 0 ); //string("0")
        var_dump( 'hi' ==  0 ); // bool(true)
        
        var_dump( (int) '1hi' ); // int(1)
        var_dump( 1 == '1hi' ); // bool(true)
        

        它有一个对应的(类型杂耍的)不等式运算符,!=

        ===

        === 运算符,称为“相同”运算符,对两个操作数的值 类型执行严格检查,并且不执行任何隐式转换。因此,"0" 不是 === 0"1234 test" 不是 === 1234

        <?php
        var_dump( '1234 test' === 1234 ); // bool(false)
        

        它有一个对应的(严格的)不等式运算符,!==

        怪癖

        请注意,=== 运算符对某些人认为奇怪的对象的行为。假设我们有class A 和变量$a$b,定义如下:

        <?php
        class A { 
          public $property = 'default value';
        }
        $a = new A();
        $b = new A();
        

        您可能期望var_dump($a === $b); 输出bool(true)。它实际上会返回 false。在对象上使用时,运算符实际上检查两个操作数是否是对同一个对象的引用。在这种情况下,== 运算符通过检查对象的属性来工作,因此 $a == $b

        PHP 手册链接

        【讨论】:

        • 注意:var_dump(0 == 'abc'); 给出 truevar_dump(0 == '1abc'); 计算结果为 false
        • 请注意,C 也可以进行类型杂耍,唯一的区别是它有一组更小的隐式转换。将intfloat 进行比较将导致精度损失,如果int 为负数,则将unsignedint 进行比较将产生意想不到的结果。
        • 请注意,这与 JavaScript 中的行为不同。 123 == "123 asd" 返回 false 而 123 == "0123" 返回 true。
        • @rabudde 因为(int) '1abc' === 1。这与1234 == '1234 test'的情况类似
        • @Lusitanian 你是对的。我只想给出一个提示,当您不注意并快速编写代码时会发生什么。当然,您的示例结果最后是相同的,但是您强制(!)整数转换。并且我想展示松散比较与 0 的一点特殊含义。
        【解决方案6】:

        您正在松散地比较两种不同类型的数据(整数和字符串)。 PHP 有一个非常详细的图表,说明了在使用松散比较二元运算符 (==) 时比较在其系统中的工作方式:

        http://php.net/manual/en/types.comparisons.php

        如果要确保类型也同步,即它们都是整数或都是字符串,请使用强类型比较运算符 (===)。

        注意,当使用这个操作符时,这也会返回false:

        1234 === '1234'
        

        如果在比较时不确定自己的类型,可以将强类型比较与 PHP 类型转换结合起来:

        $a = 1234;
        $b = '1234';
        
        if ($a === $b) { }            // Will not fire, as it is false
        if ((int)$a === (int)$b) { }  // Will fire, as it is true
        

        【讨论】:

          猜你喜欢
          • 2017-09-28
          • 2017-04-28
          • 1970-01-01
          • 2019-06-29
          • 1970-01-01
          • 1970-01-01
          • 2012-07-26
          • 2014-05-19
          相关资源
          最近更新 更多