<?php
@expression // 抑制 expression 执行产生的错误/警告/通知
仅影响当前表达式,不影响后续代码。
E_ERROR、E_WARNING、E_NOTICE、E_DEPRECATED 等运行时错误。E_CORE_ERROR)、自定义错误处理器(set_error_handler)中返回 false 时的错误。null。error_get_last() 仍可获取被抑制的最后错误信息。<?php
// 连接可能失败的服务,不希望中断主流程
$conn = @mysqli_connect($host, $user, $pass, $db);
if (!$conn) {
error_log("DB connect failed: " . mysqli_connect_error());
// 降级处理...
}
<?php
$page = @$_GET['page'] ?? 1; // PHP 7+ 推荐用 ?? 替代
// 旧版写法
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
<?php
// 文件不存在时 file_get_contents 发出 Warning
$content = @file_get_contents($filepath);
if ($content === false) {
// 处理失败
}
| 危害 | 说明 |
|---|---|
| 掩盖真实 Bug | 拼写错误、类型错误、逻辑错误被静默吞噬,排查极难 |
| 性能损耗 | PHP 内部需修改错误报告上下文,频繁使用可测量到开销 |
| 破坏错误处理器 | 自定义 set_error_handler 无法捕获被 @ 抑制的错误 |
| 调试困难 | 生产环境错误日志缺失,事后无法复现 |
| 场景 | 不推荐 | 推荐 |
|---|---|---|
| 数组键可能不存在 | @$arr['key'] | $arr['key'] ?? $default / isset($arr['key']) |
| 变量可能未定义 | @$var | isset($var) / !!!$var (PHP 7.3+) |
| 函数可能报 Warning | @func() | 预检条件 / set_error_handler 局部处理 / try-catch (PHP 8+ 部分函数抛异常) |
| 资源连接失败 | @connect() | 检查返回值 / 捕获异常 (mysqli/PDO 可设置异常模式) |
<?php
// PHP 8+ 许多内部函数抛出 ValueError/TypeError 而非 Warning
// @ 无法抑制异常,必须用 try-catch
try {
$result = some_func($invalid_arg);
} catch (TypeError $e) {
// 处理
}
@unlink($tmpfile) 文件可能已被其他进程删除,不想产生 Warning。// @todo remove suppression。@ 是「核武器级」工具:威力大(抑制所有错误)、副作用重(掩盖 Bug、破坏调试、性能损耗)。99% 的场景有更清晰、安全、可维护的替代方案(??, isset(), 预检条件, try-catch, 自定义错误处理器)。仅在极少数「明确可控、无替代方案」的边界情况下谨慎使用,并添加注释说明理由。