【问题标题】:How come ('-' == 0) === true?为什么 ('-' == 0) === 是真的?
【发布时间】:2013-08-16 09:02:51
【问题描述】:

我在这里使用了一些爆炸式的弦乐行走:

array_walk($data, function(&$value)
{
    // Transform numerics into appropriate type numbers
    if (is_numeric($value))
    {
        $value = substr_count($value, '.') == 1 ? (float) $value : (int) $value;
    }

    // Transform dashes into nulls
    if ($value == '-')
    {
        $value = null;
    }
});

将值转换为适当的类型,以及一些特殊的字符处理。

我在哪里偶然发现了一个有趣的错误,嗯?

虫子

我很惊讶,每一个初始值为string(1) '0' 的条目最终都是null

起初,我认为问题出在(float)(int) 类型转换上,但在调试后:

var_dump((float) '0', (int) '0');

我看到不是这样,得到了预期的结果:

float(0)
int(0)

我花了一段时间来尝试调试,目前似乎很明显的弱类型检查,但是,一旦我这样做了,我就震惊了:

var_dump('-' == 0);

上面的表达式似乎是:

bool(true)

现在,在写的时候,我想我应该再调试一些,所以:

var_dump( '=' == 0 );
var_dump( 'What a lovely nonsense?' == 0 );
var_dump( 0 == 'DAFUQ?' ); // maybe it's because of order? It's PHP, world of miracles, you know...

而且,上面列出的每个表达式都是bool(true)

好吧,也许这是因为 PHP 在内部神秘地将表达式转换为 (bool)

var_dump( (bool) '-' == 0 );

没有:

bool(false)

那么,那么,那么……

我在这里做了一个测试用例:http://codepad.org/smiEvsDj
该问题存在于 5.2.5(键盘)、5.4.3(朋友)和 5.4.17(我的实际环境)中。

这个功能/错误/what-the-F-actually-is-this背后的原因是什么?

【问题讨论】:

  • 只需阅读有关松散类型的manual pages 并克服它.... 多年来,这种带有松散类型比较的假定issue 已经被哈希到死
  • If you compare a number with a string or the comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically. Source
  • 我只有一件事要说... DUCK PHP!

标签: php casting type-conversion


【解决方案1】:

您偶然发现了人们对 PHP 作为一种语言的主要抱怨之一:“==”运算符不具有传递性这一事实。

任何字符串"foo" == TRUE,因为 PHP 人希望它能够工作:

if ($string) {
    // do something if $string is set
}

然而,将字符串转换为数字(当您使用“==”时,PHP 总是会尝试这样做),"foo" == 0

当然,TRUE != 0。这是处理 PHP 时的一大痛点,这不合逻辑,但却是现实。

【讨论】:

    【解决方案2】:

    它试图从你的字符串中解析数字,没有找到任何数字并自动恢复为 0。我认为...

    例如它看到'What a lovely nonsense?' == 0,看到您正在比较整数,并尝试将What a lovely nonsense? 转换为整数。由于没有数字,它默认为 0,并认为 LHS == RHS 所以返回 true

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-16
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      • 2018-11-23
      • 1970-01-01
      相关资源
      最近更新 更多