← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Error Suppression Operator (@)

Code Quality PHP 5.0+ Beginner
debt(d3/e3/b3/t7)
d3 Detectability Operational debt — how invisible misuse is to your safety net

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.

e3 Effort Remediation debt — work required to fix once spotted

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.

b3 Burden Structural debt — long-term weight of choosing wrong

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.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

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.

About DEBT scoring →

Also Known As

@ operator silence operator error suppressor

TL;DR

Prefixing a PHP expression with @ silently suppresses all errors and warnings it generates — hiding bugs instead of handling them.

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

@ is a quick fix for annoying warnings — it hides the symptom while the underlying problem (missing file, invalid URL, failed database connection) silently corrupts the application state.

Why It Matters

@ suppressed errors make debugging nearly impossible — the error is gone, the application silently continues with a null or false value, and the failure surface is invisible.

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

✗ Vulnerable
// 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
✓ Fixed
// 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

Added 16 Mar 2026
Edited 22 Mar 2026
Views 68
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 1 ping F 0 pings S 0 pings S 0 pings M 2 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 0 pings W 2 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
ChatGPT 12 Amazonbot 9 Google 6 Perplexity 4 Ahrefs 4 SEMrush 3 Scrapy 3 Majestic 2 DuckDuckGo 2 Unknown AI 1 Claude 1 Bing 1 Meta AI 1
crawler 48 crawler_json 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Delete every @ operator and replace it with proper error handling — the @ operator silences the error but doesn't fix the problem, and in PHP 8 it no longer suppresses fatal errors
📦 Applies To
PHP 5.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
@file_get_contents(); @unlink(); @ before any function call suppressing legitimate errors
Auto-detectable: ✓ Yes phpcs phpstan rector
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Low ✗ Manual fix Fix: Medium Context: Line Tests: Update
CWE-390


✓ schema.org compliant