hheedat
V2EX  ›  PHP

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

  •  
  •   hheedat · Oct 18, 2017 · 7253 views
    This topic created in 3136 days ago, the information mentioned may be changed or developed.

    今天同事遇到类似这样一个坑,先不说 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 replies    2017-10-20 19:26:30 +08:00
    tomczhen
        1
    tomczhen  
       Oct 18, 2017   ❤️ 3
    这是 Feature 不是 Bug。:doge:
    blankme
        2
    blankme  
       Oct 18, 2017
    不同类型的东西为什么要比较
    ysoserious
        3
    ysoserious  
       Oct 18, 2017   ❤️ 1
    写 PHP 的时候有个习惯就是外部获取的数据先进行一次强制的类型转换,然后再用。
    takanasi
        4
    takanasi  
       Oct 18, 2017
    py 大法好
    >>> 'apple'==0
    False
    seognilV2
        5
    seognilV2  
       Oct 19, 2017 via Android
    这叫隐式类型转换
    wintercoder
        6
    wintercoder  
       Oct 19, 2017
    这几天也刚遇到
    echo "aa" == 0; 是 true
    bazingaterry
        7
    bazingaterry  
       Oct 19, 2017 via iPhone
    嚇了我一跳 - -
    onlyhot
        8
    onlyhot  
       Oct 19, 2017 via iPhone   ❤️ 4
    既然你们写 php,为什么你们连这点基础知识都没有?还敢吐槽这是坑?
    changwei
        9
    changwei  
       Oct 19, 2017 via Android   ❤️ 1
    楼主再去写一下 javascript 估计会发现更多神奇的事情
    Tunar
        10
    Tunar  
       Oct 19, 2017 via Android   ❤️ 2
    你是 c131-2 还是 c64-1 的莫蒂?
    sagaxu
        11
    sagaxu  
       Oct 19, 2017 via Android
    好吧,我也掉坑里了。php 和 js 是主流语言里语法设计最垃圾的。
    simapple
        12
    simapple  
       Oct 19, 2017
    同一楼,这是特性
    askfilm
        13
    askfilm  
       Oct 19, 2017   ❤️ 1
    有 === 不用, 有着 php 的便利,还吐槽着, 唉~
    dobelee
        14
    dobelee  
       Oct 19, 2017 via Android
    不同类型的东西不要比较,相似的问题还有 false 和 0 的问题。
    fzhw88
        15
    fzhw88  
       Oct 19, 2017 via Android
    这是语言特性,说人家设计垃圾的也是无语。
    k9982874
        16
    k9982874  
       Oct 19, 2017 via iPhone
    这种 case 不是应该用 if ?
    byfar
        17
    byfar  
       Oct 19, 2017
    "先不说 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  
       Oct 19, 2017
    > 注意 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  
       Oct 19, 2017
    初级问题中的 2 级问题
    MushishiXian
        20
    MushishiXian  
       Oct 19, 2017
    多看 php 官方文档....
    sagaxu
        21
    sagaxu  
       Oct 19, 2017 via Android   ❤️ 2
    火锅店自助调料区,一个装屎的容器上用粗体写着醒目的一个大字,屎。提示写的很清楚了,是你自己没看清楚,所以这是特性,不要吐槽。
    b821025551b
        22
    b821025551b  
       Oct 19, 2017
    先不说 switch 这么混杂是否合适 ❌
    switch 这么混杂就是不合适⭕️
    yxn1910
        23
    yxn1910  
       Oct 19, 2017
    关于弱类型语言的 PHP 对数字和字符串进行比较时会发生什么事情应该是刚入门第一个月就该掌握的一个知识点,正确的姿势是再买一本基础书好好边做笔记边看完而不是来 v 站吐槽。
    Norie
        24
    Norie  
       Oct 19, 2017
    这不是很正常吗?
    sucaihuo
        25
    sucaihuo  
       Oct 19, 2017
    来学习一下
    iyaozhen
        26
    iyaozhen  
       Oct 19, 2017 via Android
    多看文档。有抱怨的时间还不如把这块再深入看下。比如字符串隐式转 int 的规则是怎么样的
    zgx030030
        27
    zgx030030  
       Oct 19, 2017
    你写 PHP 的 都不懂它的字符串和数值比较时的类型转换,也难怪 php 会被黑。
    Alex6
        28
    Alex6  
       Oct 19, 2017
    还是规避这种 case 比较写法吧,可以考虑用这个 strcmp 比较,类型自动转换为 string
    FYK
        29
    FYK  
       Oct 19, 2017
    @sagaxu 无关其他 ,只是觉得这个例子太好笑了。哈哈哈哈哈火锅店自助调料区放着一容器的屎 哈哈哈哈哈
    haierspi
        30
    haierspi  
       Oct 19, 2017
    很奇怪的写法... 给我的感觉就是一边吃雪糕 一边吃火锅...
    haierspi
        31
    haierspi  
       Oct 19, 2017
    建议还是 写 if elseif 用 === 来判断更为准确.. 不然就会出现 PHP 自动转换类型
    hheedat
        32
    hheedat  
    OP
       Oct 19, 2017
    大家说的都很有道理,谢谢了
    gouchaoer
        33
    gouchaoer  
       Oct 19, 2017 via Android
    你的观点在于 switch 匹配用了==而为何不用===的问题,实际上这个问题很简单,当你从用户输入或者数据库读出的数据都是 string,很多时候你根本不知道一个变量是 int 还是 string,这个时候就觉得这么做有合理性
    gouchaoer
        34
    gouchaoer  
       Oct 19, 2017 via Android
    @sagaxu 我不同意,php 语法规规矩矩,py 的语法才是屎
    gouchaoer
        35
    gouchaoer  
       Oct 19, 2017 via Android
    go 的语法也是屎
    老实按照 java/c 的惯例来多好,非要特立独行
    cncqw
        36
    cncqw  
       Oct 19, 2017
    楼主基础不好还像发现新大陆一样
    hard2reg
        37
    hard2reg  
       Oct 20, 2017
    这个坑。。我踩过
    mol310
        38
    mol310  
       Oct 20, 2017
    php 是世界上最好的语言 ^0^
    8355
        39
    8355  
       Oct 20, 2017
    多年前在 segmentfault 上提过这个问题
    http://php.net/manual/zh/types.comparisons.php
    carlclone
        40
    carlclone  
       Oct 20, 2017 via Android
    php 被鄙视多亏了楼主这种人基数过大
    jevonszmx
        41
    jevonszmx  
       Oct 20, 2017
    @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


    官方手册真的要常读~
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1199 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 103ms · UTC 23:18 · PVG 07:18 · LAX 16:18 · JFK 19:18
    ♥ Do have faith in what you're doing.