前言
在 PHP 的一些歷史遺留設計中,許多函數在出錯或失敗時會返回 false、-1 或 null 等特殊值。如果你沒有對這些返回值進行正確檢查,就可能導致程序行為不符合預期。
舉個例子
$content = file_get_contents('foobar.json');
$foobar = json_decode($content);
在這段代碼中:
- 如果
foobar.json不存在,file_get_contents()會返回false並觸發一個 warning; json_decode()接收到false會返回null;- 之後的代碼仍會繼續執行,錯誤很可能在後續某個環節才暴露出來,而不是在問題發生的當下就被發現。
如果希望更加嚴謹地處理這些情況,就需要顯式地進行錯誤檢查:
$content = file_get_contents('foobar.json');
if ($content === false) {
throw new FileLoadingException('Could not load file foobar.json');
}
$foobar = json_decode($content);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new FileLoadingException('foobar.json does not contain valid JSON: ' . json_last_error_msg());
}
通過在每一步中主動檢測錯誤並拋出異常,可以讓你在問題出現的第一時間就得到提示,而不是等到後續某個異常行為發生後再去排查源頭。
更好的方案
推薦使用這個包:thecodingmachine/safe。它對 PHP 的一些內置函數進行了包裝,讓這些函數在出錯時拋出異常,而不是返回 false。
使用方式如下:
use function Safe\file_get_contents;
use function Safe\json_decode;
$content = file_get_contents('foobar.json');
$foobar = json_decode($content);
這段代碼的行為現在和前面手動處理異常的代碼效果一致:一旦發生錯誤,就會立刻拋出異常,阻止程序繼續運行。同時,代碼也更加簡潔、易讀。
更進一步
使用 PHPStan 檢查
該包還提供了 PHPStan 的擴展功能,它可以幫助你分析代碼中是否使用了未安全包裝的內置函數,並建議你使用對應的安全版本,從而避免未來產生不安全調用。
使用 Rector 自動替換
此外,它也提供了針對 Rector 的規則,可以自動替換你代碼中對原生函數的調用為安全版本。
⚠️ 注意:Rector 僅負責函數替換,並不會檢查你是否已經手動進行過錯誤處理。因此,仍需結合代碼審查和測試使用。
寫在最後
如果你對其實現方式感興趣,建議查閲其源碼與文檔,評估該庫是否適合你的項目。
參考鏈接
- Safe PHP: throwing exceptions instead of returning false
- thecodingmachine/safe on GitHub
本文使用 ChatGPT 進行了排版優化、專有名詞處理、錯別字、錯誤用詞處理。
本作品採用 知識共享署名 4.0 國際許可協議 進行許可。