Error Suppression Operator (@)
debt(d3/e3/b3/t7)
Closest to 'default linter catches the common case' (d3). The detection_hints list phpcs, phpstan, and rector — all widely-used default or near-default static analysis tools in PHP projects. The code_pattern is explicit (@ before any function call), making automated detection straightforward. Scores d3 exactly: not a compiler error, but caught by standard tooling without specialist configuration.
Closest to 'simple parameterised fix' (e3). The quick_fix says 'delete every @ operator and replace it with proper error handling.' The common_mistakes show the fix is a consistent replacement pattern (@ prefix → explicit guard check or null coalescing operator). Each individual fix is a small, localised change, but it must be repeated across every occurrence in the codebase. Not a one-liner patch (e1) because understanding the underlying failure reason is required per-site, but not a multi-file refactor either.
Closest to 'localised tax' (b3). The applies_to contexts are broad (web, cli, queue-worker), meaning the operator can appear anywhere in PHP code. However, each usage is independently localised — a suppressed @fopen() does not structurally reshape the codebase the way a shared mutable state would. The burden is a per-usage debugging tax rather than a systemic architectural constraint, placing it at b3.
Closest to 'serious trap' (t7). The misconception field directly states: '@ is a quick fix for annoying warnings — it hides the symptom while the underlying problem silently corrupts the application state.' This contradicts how error handling works in most other languages, where ignoring an error requires explicit intent (try/catch, if/else). A competent developer unfamiliar with PHP would reasonably expect @ to be a benign silencer, not a mechanism that causes null/false propagation and invisible failures. Stops short of t9 because @ is a documented and well-known PHP gotcha, not an always-wrong pattern.
Also Known As
TL;DR
Explanation
The @ operator suppresses all PHP errors from the expression, including fatal errors in PHP 7 (in PHP 8, @ no longer suppresses fatal errors). It is a code smell in almost every case: instead of suppressing the error, handle it — check if a file exists before fopen(), validate the URL before file_get_contents(), use error-returning functions and check their return value. The only legitimate use is third-party library calls that emit unavoidable deprecation notices in legacy code.
Common Misconception
Why It Matters
Common Mistakes
- @fopen($file) instead of checking file_exists() first.
- @unlink($file) instead of if (file_exists($file)) unlink($file).
- @$arr['key'] instead of $arr['key'] ?? null.
- Using @ on an entire function call when only one operation inside it can fail.
Code Examples
// Suppressing errors — bugs hidden:
$fp = @fopen($path, 'r'); // File missing? $fp is false, no error
$data = @file_get_contents($url); // URL invalid? $data is false, silent
@unlink($tmpFile); // Already deleted? Silently ignored
$val = @$config['missing_key']; // Undefined key? Silently null
// Handle errors explicitly:
if (!file_exists($path)) throw new FileNotFoundException($path);
$fp = fopen($path, 'r');
$data = file_get_contents($url);
if ($data === false) throw new HttpException("Failed to fetch $url");
if (file_exists($tmpFile)) unlink($tmpFile);
$val = $config['missing_key'] ?? null; // Intentional null default