<?php $arr = array("Linux"); if (in_array(0, $arr)) { echo "match"; } ?>
執行以上代碼,0和字符串是可以匹配成功的。
原因是在in_array,如果比較的類型不匹配,並且第一個參數是0,它會返回true(不正確)。
查手冊:If the third parameter strict is set to TRUE then the in_array() function will also check thetypes of theneedle in thehaystack.
加上類型比較后返回false(正確)
經查閱相關資料如下:
1.情況一
$test = 'a'; $array = array('a', 'b', 'c'); if (in_array($test, $array)) { echo 'in array'; } else { echo 'no'; } //output: in array
2.情況二
$test = 'other value'; $array = array('a', 'b', 'c'); if (in_array($test, $array)) { echo 'in array'; } else { echo 'no'; } //output: no
------------------------ 看似一切都正常的分割線 -----------------------
3.情況三
$test = 0; $array = array('a', 'b', 'c'); if (in_array($test, $array)) { echo 'in array'; } else { echo 'no'; } //output: in array
難以置信,這不坑爹嗎,0不在列表中,但是這個函數返回true。這個函數很常用,所以當某些巧合出現后,就會導致不可預料的錯誤。
一開始我猜測in_array函數除了在values中尋找,還會去尋找keys,后來發現不是這樣的。
4.情況四
$test = '0'; $array = array('a', 'b', 'c'); if (in_array($test, $array)) { echo 'in array'; } else { echo 'no'; } //output: no
是不是很有意思
5.原來是因為:
http://www.php.net/manual/en/language.operators.comparison.php
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
php比較數字和字符串時,會嘗試將字符串轉換為數字再進行比較。 例子中的 'a', 'b', 'c' 轉成數字都是0,所以和0相等,in_array就返回了true。
6.如何避免
PHP的類型戲法是把雙刃劍,有時候很爽,有時候很賤。
所以當in_array的needle與array中的值類型是否相同還不確定時,最好設置in_array函數的第三個參數 strict = true,這樣在檢查的時候會檢查類型,數字與字符串就不會偷偷相等,也就避免類似這種問題。
$test = 0; $array = array('a', 'b', 'c'); if (in_array($test, $array, true)) { echo 'in array'; } else { echo 'no'; } //output: no