有没有人遇到这个问题... PHP array index 同时存在 int 和 string, 这个时候 0 == 任何字符串, 这是为什么?

2021-08-30 10:58:58 +08:00
 JoeBreeze

已知解决: =====

例子

<?php
$arr = [
    'hello'  => 'world',
    'world' => 'hello',
    'what'  => 'the hell',
    '0'        => 'zero in string key',
    0         => 'zero in int key',
    1         => 'one in int key',
];

var_dump($arr);

foreach($arr as $k => $v){
    echo '-------------------'.PHP_EOL;
    echo ($k=='hello'? '√': 'X').' | '.$k .'==hello'.PHP_EOL;
    echo ($k=='world'? '√': 'X').' | '.$k .'==world'.PHP_EOL;
    echo ($k=='what'? '√': 'X').' | '.$k .'==what'.PHP_EOL;
    echo ($k=='0'? '√': 'X').' | '.$k .'==0'.PHP_EOL;
    echo ($k=='1'? '√': 'X').' | '.$k .'==1'.PHP_EOL;
}

输出:

array(5) {
  ["hello"]=>
  string(5) "world"
  ["world"]=>
  string(5) "hello"
  ["what"]=>
  string(8) "the hell"
  [0]=>
  string(15) "zero in int key"
  [1]=>
  string(14) "one in int key"
}
-------------------
√ | hello==hello
X | hello==world
X | hello==what
X | hello==0
X | hello==1
-------------------
X | world==hello
√ | world==world
X | world==what
X | world==0
X | world==1
-------------------
X | what==hello
X | what==world
√ | what==what
X | what==0
X | what==1
-------------------
√ | 0==hello
√ | 0==world
√ | 0==what
√ | 0==0
X | 0==1
-------------------
X | 1==hello
X | 1==world
X | 1==what
X | 1==0
√ | 1==1
2206 次点击
所在节点    PHP
11 条回复
javalaw2010
2021-08-30 11:04:12 +08:00
隐式类型转换,字符串和 int 类型比较时,会先把字符串转换成 int 类型,再做比较。
zhizunzz
2021-08-30 11:13:14 +08:00
== 和 ===区别就是自动类型转换
JoeBreeze
2021-08-30 11:14:28 +08:00
@javalaw2010 但是... 非空字符串, 不是应该转换成 1 吗
JoeBreeze
2021-08-30 11:14:46 +08:00
@zhizunzz [OK]
guanguans
2021-08-30 11:34:26 +08:00
Rache1
2021-08-30 12:51:09 +08:00
因为在 8.0 以前,数字和字符串进行比较,会把字符串转成数字,而自 8.0 开始,数字和字符串进行比较时,会把数字转成字符串。

php 的字符串转数字在一定程度上和 js 的 parseInt 有些类似,如果一个字符串是以数字开头的,那么就会尽量转化成符合数字的部分,否则就是 0 。

比如 1abced 转成数字就是 1,而 1e3abced 转成数字时,会解析 1e3,故而返回 1000 。(float)'1.5.1.1' 会返回 1.5

其他的找不到数字开头的,不会像 js 那样转为 NaN,而是转为 0,所以就有了上面的结果。
Rache1
2021-08-30 12:55:19 +08:00
😂 意外发现个问题,

在 php 8 中,因为数字和字符串进行比较时,会把数字转成字符串进行比较。

但是 var_dump('0'=='00000'); 这样也是为 true 的
javalaw2010
2021-08-30 13:28:23 +08:00
@Rache1 其实不是个问题而是个 feature,因为‘0’和‘00000’都是数字字符串( numeric string ),所以会被转成数字进行比较。可以看 5 楼那个链接里面的说明。
buffzty
2021-08-30 13:53:51 +08:00
没遇到过,我从没写过双等号
Rache1
2021-08-30 18:25:10 +08:00
@javalaw2010 看起来是上面提到的这个 “Numeric strings” 的 feature,之前还没注意过 ,顺带看到那个 rfc
jfcherng
2021-08-31 07:59:32 +08:00
switch ... case 同坑

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/798784

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX