PHP array_filter把0刪掉了:保留零值與JSON列表的寫法

商品庫存明明是0,PHP整理欄位後卻不見了?先找程式裡有沒有直接呼叫array_filter($values)。省略判斷函式時,它會移除PHP視為空的值,整數0與字串'0'都在其中。若0代表缺貨、免費或未使用次數,這樣清資料就可能把有意義的值一起刪掉。

要修正這個問題,先說清楚哪些值應該移除。下面用虛構資料示範:只去掉空字串與null,保留兩種零;若結果要作為JSON列表交給前端,再把數字索引排回連續順序。

先重現:不用callback,兩種零都被移除

把以下程式存成filter-demo.php,在已安裝PHP的練習環境執行php filter-demo.php。這段程式只處理記憶體裡的陣列,不會寫入商品資料庫。

<?php
$values = [0, '0', '', null, 12];
$filtered = array_filter($values);
var_export($filtered);
echo PHP_EOL;
echo json_encode($filtered), PHP_EOL;

結果只剩索引4的12,JSON會是{"4":12}。這裡有兩個不同原因:預設篩選把零值移除,而array_filter()保留原本的鍵。不是JSON把0刪掉,也不是前端憑空把陣列改成物件。

只刪空字串與null:用嚴格比較保留0

如果你的需求確實是「只刪空字串與null」,把篩選條件寫出來。這裡要用!==,避免把不同型別先轉換後再比較。

<?php
$values = [0, '0', '', null, 12];
$filtered = array_filter($values, static function ($value) {
    return $value !== '' && $value !== null;
});
var_export($filtered);
echo PHP_EOL;
echo json_encode($filtered), PHP_EOL;

現在索引0、1、4分別保留整數0、字串’0’與12。JSON結果是{"0":0,"1":"0","4":12}:零回來了,但鍵還沒有重排,因此仍是JSON物件。

這個條件也會保留false、空陣列與只含空白的字串。它們是否有效,要依欄位規格決定;例如庫存欄位還需要另外驗證數字與允許範圍。不要把「保留0」誤當成整份輸入已驗證合格。

前端要JSON列表,再用array_values重排

當介面約定回傳列表,例如[0,"0",12],可在篩選後呼叫array_values()。它回傳值組成的新陣列,數字索引從0重新連續排列。

<?php
$values = [0, '0', '', null, 12];
$filtered = array_filter($values, static function ($value) {
    return $value !== '' && $value !== null;
});
$list = array_values($filtered);
echo json_encode($list), PHP_EOL;
// [0,"0",12]

PHP的json_encode()會把從0開始的連續數字鍵陣列編碼成JSON陣列;鍵不連續時,則會把鍵寫成物件屬性。重排只改陣列鍵,不會把字串’0’變成整數0。如果原本的鍵就是商品ID或欄位名稱,應保留它們,不能為了得到方括號就一律套用array_values()。

接回網站前,比較原始值與回傳格式

先在練習環境比較上面三段結果,再回到自己的處理程式找出篩選步驟。若資料在進入array_filter()前已經缺少0,要往前查讀取或轉型;若PHP輸出已有0,前端仍顯示空白,就改查前端的條件判斷。

確認API原本約定的是列表還是以ID為鍵的物件,再選擇是否重排。修正時保留其他欄位規則,尤其是null、false與空白字串的處理,不要順手把整份回應都改成同一種結構。另一種容易混淆的PHP問題是JSON解碼得到null;那屬於解碼結果與錯誤判斷,和這裡的篩選條件不同。

參考資料

原文鏈接:https://wntheme.com/php-array-filter-zero-json-list/,轉載請註明出處。
0

評論0

顯示驗證碼
沒有帳號?註冊  忘記密碼?