在PHP 中, array_filter()是一個非常常用的數組函數,用於根據回調函數的結果篩選數組中的元素。它的用法看似簡單,但很多開發者在使用時,尤其是寫回調函數時,會對其返回值的“布爾意義”感到疑惑。
比如說,有人寫出如下代碼:
$input = [0, 1, 2, 3, 4, 5];
$result = array_filter($input, function($value) {
return $value % 2; // 希望保留奇數
});
print_r($result);
他們可能期望輸出為[1, 3, 5] ,結果也是這樣。但是,如果對這個例子稍作修改,就容易引起混淆:
$input = [0, 1, 2, 3, 4, 5];
$result = array_filter($input, function($value) {
return $value % 2 == 0; // 希望保留偶數
});
print_r($result);
很多人以為返回true就保留元素,返回false就過濾掉,這確實沒錯。但是關鍵在於——PHP 是動態類型語言,回調函數返回的任何值都會被強制轉換為布爾值。
PHP 中的這些值會被轉換為false :
布爾值false
整型0
浮點型0.0
空字符串''或'0'
空數組[]
null
因此,當你寫出以下代碼時:
$input = ['a', '', 'b', '0', 'c'];
$result = array_filter($input);
print_r($result);
你會發現輸出是:
Array
(
[0] => a
[2] => b
[4] => c
)
沒有指定回調函數時, array_filter()默認使用布爾強制轉換來判斷是否保留一個元素。所以空字符串''和'0'都被過濾掉了——因為它們被轉換為了false 。
這時很多人就會困惑:“我明明有值,為什麼被過濾掉了?”
更進一步的誤解通常出現在開發者使用回調時返回了非布爾類型:
$input = [1, 2, 3, 4, 5, 6];
$result = array_filter($input, function($value) {
return $value & 1; // 使用按位與判斷奇數
});
print_r($result);
這段代碼是沒錯的,但可能會讓初學者抓狂。 $value & 1的結果是0或1 ,當$value是偶數時結果是0 ,會被轉換成false ,於是被過濾掉。這時候你必須理解:不是返回1或0的數值本身決定了是否保留元素,而是這些值在布爾環境下的表現。
還有一點是很多人沒注意到的: array_filter()保留了原數組的鍵名。你如果希望重建索引,可以使用array_values() :
$result = array_values(array_filter($input, function($value) {
return $value > 2;
}));
比如你要從一組URL 中過濾掉沒有token參數的鏈接:
$urls = [
'https://m66.net/page1?token=abc',
'https://m66.net/page2',
'https://m66.net/page3?token=xyz',
];
$filtered = array_filter($urls, function($url) {
$parts = parse_url($url);
if (!isset($parts['query'])) {
return false;
}
parse_str($parts['query'], $query);
return isset($query['token']);
});
print_r($filtered);
這段代碼的回調函數中明確返回了布爾值( true或false ),這樣就不會被類型轉換搞混。
很多人不理解array_filter()回調函數返回值的“布爾意義”,歸根結底是對PHP 中“真假值”理解不深。要寫出可靠的array_filter()回調函數,請記住:
回調函數的返回值會被轉換為布爾值。
不要直接依賴某個類型(如數字、字符串)是否“有值”,而要明確返回true或false 。
如果你的意圖是清晰的邏輯判斷,請顯式寫出布爾表達式。
這樣一來,你就能徹底掌握這個強大而容易誤解的函數啦!