[英]Why does in_array() return unexpected / strange results?
為什么in_array()
有時表現得如此奇怪並且會返回如此意外的結果?
我們來看幾個例子:
$arrayWithTrue = ['Andreas', 'Philipp', true];
$arrayWithNull = [1, 2, 3, null];
$arrayWithMinusOne = [-1];
var_dump(in_array('Gary', $arrayWithTrue)); // returns bool(true)
var_dump(in_array(0, $arrayWithNull)); // returns bool(true)
var_dump(in_array(true, $arrayWithMinusOne)); // returns bool(true)
咦? 這里發生了什么事!?
(幾年前,我開始對這種奇怪的行為感到疑惑。我認為這對某些人來說可能有用,因此我輸入了這個問題。)
使用in_array()
始終使用第三個參數strict true
:
$arrayWithTrue = ['Andreas', 'Philipp', true];
$arrayWithNull = [1, 2, 3, null];
$arrayWithMinusOne = [-1];
var_dump(in_array('Gary', $arrayWithTrue, true)); // returns bool(false)
var_dump(in_array(0, $arrayWithNull, true)); // returns bool(false)
var_dump(in_array(true, [-1], true)); // returns bool(false)
因此,當您使用in_array()
並將true
作為第三個參數時,搜索值與數組之間的比較是嚴格完成的,這意味着in_array()
工作方式與您可能期望的一樣。
(參數strict也在php.net文檔中描述。)
如果沒有將參數strict設置為true,則搜索值與數組的每個值之間的比較是通過相等而不是通過標識來完成的。 這意味着值的類型無關緊要,因此PHP將值內部轉換為相同的數據類型,以便能夠比較它們。
這意味着在第一個示例中,搜索到的值'Gary'
在與true
進行比較時會轉換為布爾值,因此會導致true
與true
的比較,這顯然是true
。
第二個數組也是如此,其中0
最后與null
進行比較,結果為true
,即使0
顯然與null
(例如,當您處理數字和/或函數結果時,這可能特別棘手,其中null
可以表示空值而不是0
)。
然后第三個數組看起來很奇怪,因為我們檢查數組中的值true
,它只包含-1
,但in_array()
仍然返回true
以進行比較。 在這種情況下, -1
將轉換為布爾值true
。 所以兩個方向的問題都是一樣的。
您可以在此Stack Overflow答案中找到有關PHP中比較問題的更多示例(因為這與==
/ ===
相同)。
不幸的是,調用in_array()
時strict參數的默認值是......好吧,是的, false
。 : - / PHP和它的輸入...
如果沒有將strict參數設置為true
您應該永遠不會調用in_array()
。 如果沒有混合類型的數組,並且只檢查具有相同類型的值,則in_array()
將按預期工作。 看這個例子:
$arrayWithStrings = ['Andreas', 'Philipp', 'Friedrich'];
var_dump(in_array('Gary', $arrayWithStrings)); // returns bool(false)
所以至少這可以按預期工作。 但在我看來,總是用嚴格的 true
調用in_array()
要容易得多。 (與“SQL注入問題”類似...只是總是使用PDO和預處理語句,所以你是安全的,即使它是一個沒有可變參數的查詢。你總是安全的。)
你絕對應該用嚴格的 true
調用in_array()
。 但是有一個缺點,我想提一下(盡管很明顯)。 在調用in_array()
時,您必須使用正確的類型:
$arrayWithNumbers = [1, 2, 3];
var_dump(in_array('1', $arrayWithNumbers, true)); // returns bool(false)
但是當你知道比較數字時,你可以使用Type Casting:
$arrayWithNumbers = [1, 2, 3];
var_dump(in_array((int)'1', $arrayWithNumbers, true)); // returns bool(true)
// Comparing false with an empty array
var_dump(in_array(false, [[]])); // returns bool(true)
好吧,是的...只需使用嚴格設置為true
。 ;-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.