PHP找到第一項卻說沒有?array_search的0要這樣判斷

PHP搜尋陣列時,明明第一項就是要找的商品代碼,程式卻顯示「找不到」?先看你是不是把array_search()的結果直接放進if。它回傳的是鍵,不是單純的成功或失敗:找到第一項時,鍵可能是整數0;沒找到才回傳布林值false。

先把回傳值印出來

用一個普通的商品代碼清單就能重現。將下面存成獨立PHP檔執行,先觀察var_dump顯示的型別。

<?php
$codes = ['starter', 'pro', 'team'];
$key = array_search('starter', $codes, true);

var_dump($key); // int(0)

if ($key) {
    echo "找到\n";
} else {
    echo "找不到\n"; // 這個判斷寫錯了
}

這裡搜尋已成功,問題出在後面的條件。整數0在布林判斷中會被當成false,所以不能用if ($key)辨認搜尋是否成功。也不要改成if (!$key)或$key == false,它們同樣會把0混進失敗分支。

只把布林false當成沒找到

需要拿回鍵來讀取或處理那一項時,明確比較回傳值是否為布林false。下面是可替換前例的完整版本。

<?php
$codes = ['starter', 'pro', 'team'];
$key = array_search('starter', $codes, true);

if ($key !== false) {
    echo '找到鍵:' . $key . "\n";
    echo '商品代碼:' . $codes[$key] . "\n";
} else {
    echo "找不到\n";
}

這次會輸出鍵0及商品代碼starter。找不到時則走else。如果要用unset($codes[$key])移除匹配項,也應放在這個成功分支裡;不要在確認結果前就把false拿去當陣列鍵,否則可能誤操作鍵0。

第三個參數true,解決的是型別匹配

array_search的第三個參數和後面的!== false各有用途。前者要求搜尋值與陣列項目型別一致,後者分清「找到鍵0」和「沒有找到」。加了第三個參數,仍不能省略結果判斷。

<?php
$ids = ['12', 12];

var_dump(array_search(12, $ids));       // int(0)
var_dump(array_search(12, $ids, true)); // int(1)
var_dump(array_search('12', $ids, true)); // int(0)

未指定嚴格比較時,數字12可以匹配字串「12」;指定true後,整數與字串會分開。商品ID若從輸入框取得字串、資料庫查詢卻得到整數,就要先定義要用哪種型別,再按規則整理資料。不要只為了讓搜尋命中而關掉嚴格比較,也不要對電話或含前導零的識別碼隨意轉成整數。

只想知道有沒有,用in_array更清楚

如果下一步不需要鍵,in_array()直接回傳布林值,可以放在條件中。第三個參數同樣可選嚴格比較。

<?php
$codes = ['starter', 'pro', 'team'];

if (in_array('starter', $codes, true)) {
    echo "清單有這個商品代碼\n";
}

這適合查詢清單是否包含某個值,不等於檢查使用者有沒有購買權限,也不是檢查鍵是否存在。若要判斷某個鍵是否在陣列中,應另外看array_key_exists();別把「查值」和「查鍵」混用。

回到原程式時,補查這幾種輸入

先測第一項、第二項及不存在的值,確認0、1和false各走正確分支。關聯陣列可能回傳字串鍵;若有重複值,array_search只回傳第一個匹配的鍵,不會列出所有結果。需要全部匹配鍵時,應選擇能回傳多個鍵的做法,而不是把單一回傳值當成整份結果。

排查時用var_dump($key)看型別,比只用echo $key更容易分清0、空字串與false。確認搜尋規則及回傳值之後,再執行更新或刪除操作,避免把搜尋失敗變成誤改第一項。

參考資料

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

評論0

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