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

PHP 的迷惑行为 0 == 'string' 为什么返回 true?

  •  
  •   krabs · 2020-10-29 10:39:32 +08:00 · 7274 次点击
    这是一个创建于 1520 天前的主题,其中的信息可能已经有所发展或是发生改变。

    代码片段中有一段代码是这样的

    $p = 'auto';
    if(intval($p) == $p){  // 0 == 'auto'
    	...   结果这个条件居然是成立的?
    }
    

    然后我通过

    var_dump(
    	intval($width) == $width,
    	0=='auto1',
    	0=='string',
    	intval($width),
    	$width
    );
    

    结果返回

    bool(true)
    bool(true)
    bool(true)
    int(0)
    string(4) "auto"
    bool(false)
    

    然后我又去 Js 控制台试了一下 0 == 'string' 返回的是 false

    为什么 int 0 会等于 string ?

    45 条回复    2020-11-28 14:51:49 +08:00
    puzzle9
        1
    puzzle9  
       2020-10-29 10:41:23 +08:00   ❤️ 2
    先了解下 == 和 === 区别
    再说这个
    krabs
        2
    krabs  
    OP
       2020-10-29 10:44:18 +08:00
    @puzzle9 所以=== 和上面的对比有什么关系 === 是带类型对比 int 肯定不和 string 成立
    但是问题是 == 不论是值 还是类型 都不成立 怎么返回 true
    jowan
        3
    jowan  
       2020-10-29 10:45:08 +08:00   ❤️ 1
    puzzle9
        4
    puzzle9  
       2020-10-29 10:47:15 +08:00
    @krabs 这就牵扯到 php 是世界上最好的语言 设计的哲学了
    楼上那个官方文档可以瞅瞅
    Chappako
        5
    Chappako  
       2020-10-29 10:48:07 +08:00   ❤️ 2
    0 是 int,"string" 想要和 0 比较,就要先转换成 int,你自己试试 intval('string')
    xoxo419
        6
    xoxo419  
       2020-10-29 10:48:23 +08:00   ❤️ 2
    0 与任何字符串进行 == 比较时都为 true

    查阅的文章: https://www.cnblogs.com/weiyalin/p/10388167.html
    devwolf
        7
    devwolf  
       2020-10-29 10:48:58 +08:00
    #3 学到了
    jay4497
        8
    jay4497  
       2020-10-29 10:49:16 +08:00
    脚本类语言存在很多类型隐式转换的,真要比就用 `===`
    jowan
        9
    jowan  
       2020-10-29 10:49:35 +08:00
    很多语法是不能相并论的 比如 js 的 'string' || false
    如果你对 PHP 或者 JS 不太熟悉 最好是快速看下他的基础语法
    有很多看似类似却又不同的东西
    eason1874
        10
    eason1874  
       2020-10-29 10:49:53 +08:00
    PHP == 不是说不带类型比较,== 是先转换类型再比较。

    数字比较字符串,字符串先被转换成数字,才进行比较。

    0=='string' 等于 0==0 所以是 true
    impl
        11
    impl  
       2020-10-29 10:50:32 +08:00   ❤️ 1
    解释器看到 0 ==,知道你要对比的是数值,所以就把后面的东西解析为数值,而'string'只能解析成数字 0
    GuangXiN
        12
    GuangXiN  
       2020-10-29 10:51:06 +08:00 via Android   ❤️ 1
    因为 int == string 会触发自动类型转换,PHP 会把所有非数值字符串转换为 0 。

    尝试 var_dump((int) 'abc');
    kuro1
        13
    kuro1  
       2020-10-29 10:54:12 +08:00
    好的 IDE 会提示你是否要用 ===
    duhui
        14
    duhui  
       2020-10-29 10:54:38 +08:00
    @xoxo419
    php > var_dump(0 == '1aaa');
    php shell code:1:
    bool(false)
    hhf
        15
    hhf  
       2020-10-29 10:56:07 +08:00
    @xoxo419 老老实实看官方文档吧,兄弟

    var_dump(1 == '2');
    hhf
        16
    hhf  
       2020-10-29 10:57:09 +08:00
    @hhf var_dump(0 == '2')
    avenger
        17
    avenger  
       2020-10-29 10:57:50 +08:00 via iPhone
    永远不要用 ==,可以加一个 php-cs-fix 自动修复
    keepeye
        18
    keepeye  
       2020-10-29 11:04:58 +08:00
    先了解下动态语言,类型不一致时是如何比较的吧
    同样是将 str 转成 int 再比较,只是 js 和 php 的转换逻辑不一样

    php:
    0 == 'auto1' -> 0 == int('auto1') -> 0 == 0 // true
    js:
    0 == 'auto1' -> 0 == parseInt('auto1') --> 0 == NaN // false

    你再试试这个 123 == '123aaaaa' ,js 和 php 就一致了
    keepeye
        19
    keepeye  
       2020-10-29 11:06:09 +08:00
    另外多嘴一句,使用 == 比较不同类型的变量是不负责任的行为,应当避免
    imdong
        20
    imdong  
       2020-10-29 12:37:38 +08:00   ❤️ 1
    intval($p) == (int) $p
    CODEWEA
        21
    CODEWEA  
       2020-10-29 13:06:13 +08:00
    你用 js 的语法 来推测 php ?这两种语言语法都不一样的
    CODEWEA
        22
    CODEWEA  
       2020-10-29 13:07:36 +08:00
    0 == 'string'
    等于
    0==(int)('string')
    Xusually
        23
    Xusually  
       2020-10-29 13:19:29 +08:00
    老问题了,php 会尝试去转化字符串到数字,看下面的🌰就懂了。
    ===============================================================================
    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. These rules also apply to the switch statement. The type conversion does not take place when the comparison is === or !== as this involves comparing the type as well as the value.

    var_dump(0 == "a"); // 0 == 0 -> true
    var_dump("1" == "01"); // 1 == 1 -> true
    var_dump("10" == "1e1"); // 10 == 10 -> true
    var_dump(100 == "1e2"); // 100 == 100 -> true
    est
        24
    est  
       2020-10-29 13:20:03 +08:00   ❤️ 3
    PHP 探测任意网站密码明文 /加密手段办法:md5('240610708') == md5('QNKCDZO')


    /t/188364
    AngryPanda
        25
    AngryPanda  
       2020-10-29 13:21:27 +08:00
    想想 '0' == 'string' 吗?
    hubqin
        26
    hubqin  
       2020-10-29 13:34:43 +08:00 via Android
    之前被 in_array 坑过,要加第三个参数为 true 进行严格比较
    des
        27
    des  
       2020-10-29 13:49:46 +08:00
    那你试试 js 的这个 0 == '',脚本语言就是会有很多这种的
    yafoo
        28
    yafoo  
       2020-10-29 14:34:08 +08:00 via Android
    前段时间,被这个特性坑惨了
    Achiii
        29
    Achiii  
       2020-10-29 14:47:08 +08:00
    还有这种坑,下次只用全等
    a591826944
        30
    a591826944  
       2020-10-29 15:15:01 +08:00
    @xoxo419 #6 错。。是 非 0 数字开头的字符串
    v2yooha
        31
    v2yooha  
       2020-10-29 16:48:38 +08:00
    php 的隐式转换,我现在涉及数字类型的判断,都会先把两个参数 is_numeric 一下,都为 true 才执行后续,或者直接用===
    v2yooha
        32
    v2yooha  
       2020-10-29 16:50:58 +08:00
    @est 这种不都用 hash_equals 了吗
    est
        33
    est  
       2020-10-29 17:48:50 +08:00
    @v2yooha 发帖的那个时候还木有。。
    lovecy
        34
    lovecy  
       2020-10-29 18:05:38 +08:00
    要么用 empty 判断空值,要么用全等判断,==这种自带各种转换的,了解了规则后再使用
    ==和===的 Map:php.net/manual/zh/types.comparisons.php
    比较和转换优先级:php.net/manual/zh/language.operators.comparison.php#language.operators.comparison.types
    zencoding
        35
    zencoding  
       2020-10-29 18:51:33 +08:00
    @xoxo419 "任何字符串"有误,比如 intval("32xxx23");
    abcd191898105
        36
    abcd191898105  
       2020-10-29 19:12:32 +08:00
    所以说 php 就很离谱了,js 的话,就是返回 false 了。来玩 js
    fucker
        37
    fucker  
       2020-10-30 01:46:38 +08:00
    看到标题我就猜到是 == 和 === 的问题了
    mostkia
        38
    mostkia  
       2020-10-30 08:15:19 +08:00
    所以我编程已经很少用==了,有些问题并没有答案,就是语言这样设计的,你得踩过无数的坑之后才能算是熟练的使用它。==和===的问题在各种语言中都有自己的解释。一般还是推荐完全等于号===,排除未知的问题。
    yc8332
        39
    yc8332  
       2020-10-30 08:54:27 +08:00
    不过类型进行比较。你也是人才了。。php 的特性就是这样,反正也不报错。
    xbchaonba
        40
    xbchaonba  
       2020-10-30 09:02:52 +08:00
    @xoxo419 和大于 0 开头的带数字的字符串比就是 false 了
    fuxkcsdn
        41
    fuxkcsdn  
       2020-10-30 09:24:49 +08:00
    我项目里,除非一些极其特殊的情况(必须加注释),谁敢用 == 进行判断,会被我拉来骂的
    no1xsyzy
        42
    no1xsyzy  
       2020-10-30 10:58:41 +08:00
    @xbchaonba '0' == '1e-10000000000000000'
    1 开头,带数字,比较结果为 true
    https://tio.run/##K8go@P/fxr4go0ChLLEoPqU0t0BD3UBdwdZWQd0wVdfQAA2oa1or2Nv9/w8A
    qq1340691923
        43
    qq1340691923  
       2020-10-30 11:22:59 +08:00
    世界上最好的语言
    xbchaonba
        44
    xbchaonba  
       2020-10-30 14:33:26 +08:00
    @no1xsyzy 牛批科学计数法都用上了,涨知识了
    hbolive
        45
    hbolive  
       2020-11-28 14:51:49 +08:00
    楼主好消息来了,PHP8 运行结果应该是 false 。。
    在 PHP8 中,数字和字符比较,会首先把数字转换成字符,再比较。我也觉得这样会比较科学。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5333 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 07:25 · PVG 15:25 · LAX 23:25 · JFK 02:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.