in_array() 預設使用鬆散比較(==),導致 0、''、null、false 互相匹配,是極易踩坑的「弱類型陷阱」。本文還原實戰場景,演示問題並給出兩種修復方案。
發票方式枚舉:0=捐贈、1=郵寄、2=索取、3=電子發票。驗證代碼:
if (!in_array($_POST['invoice_action'], [0,1,2,3])) {
throw new Exception('請選擇正確的發票方式');
}
問題:若 $_POST['invoice_action'] 不存在(null)或為空字符串,驗證竟通過!
var_dump(in_array('', [0])); // true
var_dump(in_array(null, [0])); // true
var_dump(in_array(false, [0])); // true
因 PHP 鬆散比較規則:0 == '' == null == false 均為 true。
in_array() 第三參數設為 true,啟用嚴格比較(===):
var_dump(in_array('', [0], true)); // false
var_dump(in_array(null, [0], true)); // false
var_dump(in_array(false, [0], true)); // false
修正業務代碼:
if (!in_array($_POST['invoice_action'], [0,1,2,3], true)) { ... }
將數組值轉為字符串,配合嚴格模式或不啟用嚴格模式均可:
var_dump(in_array('', ['0','1','2','3'], true)); // false
但需注意:輸入端也需轉字符串,否則 0 (int) 不等於 '0' (string)。
in_array、array_search、switch 等比較操作均建議加第三參數 true。filter_input() 或手動 isset() + 類型轉換,確保進入業務邏輯的數據類型符合預期。['donate','post','request','electronic'],從根源避免數字 0 的鬆散比較陷阱。array_search()switch ($x) { case 0: ... }(同樣用 ==)== 條件判斷統一原理:嚴格比較(===)或統一類型。