@ 是 PHP 的錯誤控制運算符,用於抑制表達式產生的錯誤信息(Notice、Warning、Error)輸出。本文詳細講解其作用機制、適用場景、性能代價與替代方案。
@$page = $_GET['page'] ?? 1; // 抑制 "Undefined array key" Notice
@$conn = mysqli_connect("host", "user", "pass", "db"); // 抑制連接失敗 Warning
// 等價於:
$page = isset($_GET['page']) ? $_GET['page'] : 1;
$conn = @mysqli_connect(...); // 函數調用前加 @
error_get_last() 可獲取throw new Exception() 不會被 @ 抑制@$a = $b + $c; 只抑制賦值表達式,不影響後續代碼| 場景 | 代碼示例 | 備註 |
|---|---|---|
| 數組鍵可能不存在 | @$val = $_POST['key']; | 推薦用 ?? 或 isset() |
| 文件操作可能失敗 | @$content = file_get_contents($file); | 需檢查返回值 === false |
| 數據庫連接失敗 | @$pdo = new PDO(...); | PDO 預設拋異常,@ 無效,需 try-catch |
| 第三方庫過時函數 | @$result = old_function(); | 臨時兼容,應盡快升級 |
error_reporting、執行表達式、恢復 error_reporting,涉及棧操作@$a = 1; 比 $a = 1; 慢約 2-3 倍(微基準,實際影響取決於調用頻率)// ❌ 差
@$val = $_GET['key'];
// ✅ 好:空合併運算符 PHP 7+
$val = $_GET['key'] ?? 'default';
// ✅ 好:isset 檢查
$val = isset($_GET['key']) ? $_GET['key'] : 'default';
set_error_handler(function($severity, $message, $file, $line) {
if ($severity & (E_NOTICE | E_WARNING)) {
error_log("[$severity] $message in $file:$line");
return true; // 不顯示,但已記錄
}
return false; // 交給默認處理器
});
; php.ini
display_errors = Off
log_errors = On
error_log = /var/log/php/error.log
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
開發環境開啟 display_errors = On,直接看到問題。
@unlink($tmpFile) 忽略文件已刪除錯誤)@ 是「止痛藥」而非「治療藥」。合理使用場景極窄,**90%+ 情況下應用顯式檢查、空合併運算符、異常處理或錯誤日誌替代**。生產環境關閉顯示錯誤、開啟記錄錯誤,才是正規軍做法。