2018-09-18
參考文獻(xiàn):
Darry_Zhao: PHP數(shù)字與字符串比較的誤區(qū)
今天工作中發(fā)現(xiàn)提供的訂單查詢接口有bug
編寫時(shí)認(rèn)為當(dāng)
- 需要下載時(shí)今缚,查詢條件中的
$is_download=1
- 不需要下載時(shí)田巴,不傳
$is_download
或$is_download=0
但是對(duì)方是這樣處理: $is_download="download"
和 不傳
結(jié)果導(dǎo)致 $download==0
成立矛洞,從而進(jìn)入了錯(cuò)誤的分支
搜索后發(fā)現(xiàn)
將一個(gè)無(wú)法轉(zhuǎn)換為數(shù)字的字符串轉(zhuǎn)化為數(shù)字匙铡,結(jié)果總是為0 愕撰,所以將其與0總是返回true篡撵。
處理方式
使用強(qiáng)類型判斷
延伸閱讀
PHP中比較運(yùn)算符的規(guī)則
- 當(dāng)兩個(gè)字符進(jìn)行比較時(shí)拴孤,比較這兩個(gè)字符的ASCII碼
- 當(dāng)兩個(gè)字符串進(jìn)行比較時(shí),從第一個(gè)字符開始挨個(gè)比較對(duì)應(yīng)的ASCII碼讨便,知道某一位置兩個(gè)字符ASCII碼不一致時(shí)給出結(jié)果充甚,如'ba'>'az','10'<'a'
- 當(dāng)一個(gè)數(shù)字與一個(gè)字符/字符串比較時(shí),首先將字符/字符串轉(zhuǎn)化為數(shù)字霸褒,再與數(shù)字進(jìn)行比較伴找,如12<'21as', 'dsa'=0,同理 'a'+10=10;
- 當(dāng)兩個(gè)數(shù)字字符串進(jìn)行比較時(shí),首先將兩個(gè)字符串當(dāng)做數(shù)字废菱,并且用科學(xué)計(jì)數(shù)法存儲(chǔ)這兩個(gè)字符串技矮,科學(xué)計(jì)數(shù)法保留小數(shù)點(diǎn)后16位,再進(jìn)行比較殊轴。
由此就會(huì)產(chǎn)生一個(gè)bug
如:
$str1 = "123456789012345678";
$str2 = "123456789012345679";
(最后一位不一樣)
在比較時(shí)會(huì)先將兩個(gè)字符串用科學(xué)計(jì)數(shù)法進(jìn)行儲(chǔ)存衰倦,因?yàn)楸A?6位小數(shù),所以結(jié)果為
$str1=1.2345678901234567E+17旁理;
$str2=1.2345678901234567E+17樊零。
結(jié)果再比較就會(huì)產(chǎn)生 $str1
等于 $str2
這樣的結(jié)果;
解決辦法為使用 ===
或者 strcmp
等字符串比較函數(shù)進(jìn)行強(qiáng)類型判斷
另外孽文,長(zhǎng)度不同驻襟、在字符串中加非數(shù)字字符等等都會(huì)引起兩個(gè)字符串的不等。例如:
$str1 = "a123456789012345678";
$str2 = "a123456789012345679";
此時(shí) $str1
和 $str2
就不相等芋哭,因?yàn)榇嬖?a
這個(gè)非數(shù)字字符沉衣,所以系統(tǒng)不會(huì)講兩個(gè)字符串當(dāng)成數(shù)字字符串進(jìn)行比較,而是使用 2.
中兩個(gè)字符串比較方法减牺。