V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
JoeBreeze
V2EX  ›  PHP

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

  •  
  •   JoeBreeze · 2021-08-30 10:58:58 +08:00 · 2169 次点击
    这是一个创建于 941 天前的主题,其中的信息可能已经有所发展或是发生改变。

    已知解决: =====

    例子

    <?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
    
    11 条回复    2021-08-31 07:59:32 +08:00
    javalaw2010
        1
    javalaw2010  
       2021-08-30 11:04:12 +08:00
    隐式类型转换,字符串和 int 类型比较时,会先把字符串转换成 int 类型,再做比较。
    zhizunzz
        2
    zhizunzz  
       2021-08-30 11:13:14 +08:00
    == 和 ===区别就是自动类型转换
    JoeBreeze
        3
    JoeBreeze  
    OP
       2021-08-30 11:14:28 +08:00
    @javalaw2010 但是... 非空字符串, 不是应该转换成 1 吗
    JoeBreeze
        4
    JoeBreeze  
    OP
       2021-08-30 11:14:46 +08:00
    @zhizunzz [OK]
    guanguans
        5
    guanguans  
       2021-08-30 11:34:26 +08:00
    Rache1
        6
    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
        7
    Rache1  
       2021-08-30 12:55:19 +08:00
    😂 意外发现个问题,

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

    但是 var_dump('0'=='00000'); 这样也是为 true 的
    javalaw2010
        8
    javalaw2010  
       2021-08-30 13:28:23 +08:00
    @Rache1 其实不是个问题而是个 feature,因为‘0’和‘00000’都是数字字符串( numeric string ),所以会被转成数字进行比较。可以看 5 楼那个链接里面的说明。
    buffzty
        9
    buffzty  
       2021-08-30 13:53:51 +08:00
    没遇到过,我从没写过双等号
    Rache1
        10
    Rache1  
       2021-08-30 18:25:10 +08:00
    @javalaw2010 看起来是上面提到的这个 “Numeric strings” 的 feature,之前还没注意过 ,顺带看到那个 rfc
    jfcherng
        11
    jfcherng  
       2021-08-31 07:59:32 +08:00
    switch ... case 同坑
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3472 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 10:56 · PVG 18:56 · LAX 03:56 · JFK 06:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.