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

神奇的 PHP 数字和字符串比较

  •  
  •   hheedat · 2017-10-18 22:36:01 +08:00 · 6566 次点击
    这是一个创建于 2600 天前的主题,其中的信息可能已经有所发展或是发生改变。

    今天同事遇到类似这样一个坑,先不说 switch 这么混杂是否合适

    function test($var)
    {
        switch ($var)
        {
            case 'apple':
                echo 'apple', PHP_EOL;
                break;
            case 0:
                echo '0', PHP_EOL;
                break;
            default:
                echo 'default', PHP_EOL;
        }
    }
    
    $arr = array('0', 0, 'apple');
    
    foreach ($arr as $value)
    {
        test($value);
    }
    
    /**
    
    结果
    
    0
    apple
    apple
    
    **/
    
    

    字符串和数字比较的时候会把字符串强制转数字,apple 就变成了 0,就相等了...

    坑爹啊

    (╯‵□′)╯︵┻━┻

    41 条回复    2017-10-20 19:26:30 +08:00
    tomczhen
        1
    tomczhen  
       2017-10-18 22:40:39 +08:00   ❤️ 3
    这是 Feature 不是 Bug。:doge:
    blankme
        2
    blankme  
       2017-10-18 22:53:56 +08:00
    不同类型的东西为什么要比较
    ysoserious
        3
    ysoserious  
       2017-10-18 23:08:15 +08:00   ❤️ 1
    写 PHP 的时候有个习惯就是外部获取的数据先进行一次强制的类型转换,然后再用。
    takanasi
        4
    takanasi  
       2017-10-18 23:11:18 +08:00
    py 大法好
    >>> 'apple'==0
    False
    seognilV2
        5
    seognilV2  
       2017-10-19 00:23:46 +08:00 via Android
    这叫隐式类型转换
    wintercoder
        6
    wintercoder  
       2017-10-19 01:07:12 +08:00
    这几天也刚遇到
    echo "aa" == 0; 是 true
    bazingaterry
        7
    bazingaterry  
       2017-10-19 02:02:27 +08:00 via iPhone
    嚇了我一跳 - -
    onlyhot
        8
    onlyhot  
       2017-10-19 02:10:18 +08:00 via iPhone   ❤️ 4
    既然你们写 php,为什么你们连这点基础知识都没有?还敢吐槽这是坑?
    changwei
        9
    changwei  
       2017-10-19 05:34:29 +08:00 via Android   ❤️ 1
    楼主再去写一下 javascript 估计会发现更多神奇的事情
    Tunar
        10
    Tunar  
       2017-10-19 07:58:32 +08:00 via Android   ❤️ 2
    你是 c131-2 还是 c64-1 的莫蒂?
    sagaxu
        11
    sagaxu  
       2017-10-19 08:06:34 +08:00 via Android
    好吧,我也掉坑里了。php 和 js 是主流语言里语法设计最垃圾的。
    simapple
        12
    simapple  
       2017-10-19 08:19:38 +08:00
    同一楼,这是特性
    askfilm
        13
    askfilm  
       2017-10-19 08:29:18 +08:00   ❤️ 1
    有 === 不用, 有着 php 的便利,还吐槽着, 唉~
    dobelee
        14
    dobelee  
       2017-10-19 08:30:56 +08:00 via Android
    不同类型的东西不要比较,相似的问题还有 false 和 0 的问题。
    fzhw88
        15
    fzhw88  
       2017-10-19 08:44:12 +08:00 via Android
    这是语言特性,说人家设计垃圾的也是无语。
    k9982874
        16
    k9982874  
       2017-10-19 09:03:48 +08:00 via iPhone
    这种 case 不是应该用 if ?
    byfar
        17
    byfar  
       2017-10-19 09:20:28 +08:00
    "先不说 switch 这么混杂是否合适"

    "混杂" 的情况你就不能这么用!同类型没问题,语言特性使然。

    "混杂" 的情况下不想 PHP 帮你自动转换,那就需要你使用全等,修改如下:

    ``` php
    function test($var)
    {
    switch (true)
    {
    case 'apple' === $var:
    echo 'apple', PHP_EOL;
    break;
    case 0 === $var:
    echo '0', PHP_EOL;
    break;
    default:
    echo 'default', PHP_EOL;
    }
    }
    ```
    WytheHuang
        18
    WytheHuang  
       2017-10-19 09:29:51 +08:00
    > 注意 switch/case 作的是松散比较。
    > 因为当运算符,函数或流程控制需要一个 integer 参数时,值会自动转换
    http://php.net/manual/zh/control-structures.switch.php
    http://php.net/manual/zh/language.types.string.php#language.types.string.conversion
    手册都写好了, 踩坑不要怪 PHP
    ioth
        19
    ioth  
       2017-10-19 09:33:18 +08:00
    初级问题中的 2 级问题
    MushishiXian
        20
    MushishiXian  
       2017-10-19 09:44:03 +08:00
    多看 php 官方文档....
    sagaxu
        21
    sagaxu  
       2017-10-19 09:57:36 +08:00 via Android   ❤️ 2
    火锅店自助调料区,一个装屎的容器上用粗体写着醒目的一个大字,屎。提示写的很清楚了,是你自己没看清楚,所以这是特性,不要吐槽。
    b821025551b
        22
    b821025551b  
       2017-10-19 10:03:38 +08:00
    先不说 switch 这么混杂是否合适 ❌
    switch 这么混杂就是不合适⭕️
    yxn1910
        23
    yxn1910  
       2017-10-19 10:08:23 +08:00
    关于弱类型语言的 PHP 对数字和字符串进行比较时会发生什么事情应该是刚入门第一个月就该掌握的一个知识点,正确的姿势是再买一本基础书好好边做笔记边看完而不是来 v 站吐槽。
    Norie
        24
    Norie  
       2017-10-19 10:59:11 +08:00
    这不是很正常吗?
    sucaihuo
        25
    sucaihuo  
       2017-10-19 11:03:26 +08:00
    来学习一下
    iyaozhen
        26
    iyaozhen  
       2017-10-19 11:16:18 +08:00 via Android
    多看文档。有抱怨的时间还不如把这块再深入看下。比如字符串隐式转 int 的规则是怎么样的
    zgx030030
        27
    zgx030030  
       2017-10-19 11:44:12 +08:00
    你写 PHP 的 都不懂它的字符串和数值比较时的类型转换,也难怪 php 会被黑。
    Alex6
        28
    Alex6  
       2017-10-19 11:56:29 +08:00
    还是规避这种 case 比较写法吧,可以考虑用这个 strcmp 比较,类型自动转换为 string
    FYK
        29
    FYK  
       2017-10-19 15:25:27 +08:00
    @sagaxu 无关其他 ,只是觉得这个例子太好笑了。哈哈哈哈哈火锅店自助调料区放着一容器的屎 哈哈哈哈哈
    haierspi
        30
    haierspi  
       2017-10-19 15:34:07 +08:00
    很奇怪的写法... 给我的感觉就是一边吃雪糕 一边吃火锅...
    haierspi
        31
    haierspi  
       2017-10-19 15:35:51 +08:00
    建议还是 写 if elseif 用 === 来判断更为准确.. 不然就会出现 PHP 自动转换类型
    hheedat
        32
    hheedat  
    OP
       2017-10-19 19:01:08 +08:00
    大家说的都很有道理,谢谢了
    gouchaoer
        33
    gouchaoer  
       2017-10-19 21:48:04 +08:00 via Android
    你的观点在于 switch 匹配用了==而为何不用===的问题,实际上这个问题很简单,当你从用户输入或者数据库读出的数据都是 string,很多时候你根本不知道一个变量是 int 还是 string,这个时候就觉得这么做有合理性
    gouchaoer
        34
    gouchaoer  
       2017-10-19 21:49:32 +08:00 via Android
    @sagaxu 我不同意,php 语法规规矩矩,py 的语法才是屎
    gouchaoer
        35
    gouchaoer  
       2017-10-19 21:52:01 +08:00 via Android
    go 的语法也是屎
    老实按照 java/c 的惯例来多好,非要特立独行
    cncqw
        36
    cncqw  
       2017-10-19 22:16:31 +08:00
    楼主基础不好还像发现新大陆一样
    hard2reg
        37
    hard2reg  
       2017-10-20 02:35:17 +08:00
    这个坑。。我踩过
    mol310
        38
    mol310  
       2017-10-20 09:38:32 +08:00
    php 是世界上最好的语言 ^0^
    8355
        39
    8355  
       2017-10-20 13:40:14 +08:00
    多年前在 segmentfault 上提过这个问题
    http://php.net/manual/zh/types.comparisons.php
    carlclone
        40
    carlclone  
       2017-10-20 14:32:26 +08:00 via Android
    php 被鄙视多亏了楼主这种人基数过大
    jevonszmx
        41
    jevonszmx  
       2017-10-20 19:26:30 +08:00
    @carlclone 哎,最近看论坛,发现真的 PHP 被鄙视,好多很业余的问题,都赖在 php 身上。。。

    php 官方文档写的非常非常清楚: http://php.net/manual/zh/control-structures.switch.php

    Note:
    注意 switch/case 作的是松散比较。

    http://php.net/manual/zh/types.comparisons.php#types.comparisions-loose


    官方手册真的要常读~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2634 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 15:22 · PVG 23:22 · LAX 07:22 · JFK 10:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.