PHP Error Levels & error_reporting
debt(d5/e3/b5/t7)
Closest to 'specialist tool catches it' (d5). The detection_hints list phpstan, phpcs, and semgrep — all specialist static analysis tools. The code_pattern (error_reporting(0) or @ suppression operator) is detectable by these tools but not by the compiler or a default linter, placing it squarely at d5.
Closest to 'simple parameterised fix' (e3). The quick_fix is essentially a one-liner (error_reporting(E_ALL) in dev), but fully correcting misuse involves also setting display_errors=Off and log_errors=On in php.ini or ini_set calls, and potentially adding set_error_handler(). That's a small coordinated fix within one config/bootstrap area, not a single-call swap, so e3 rather than e1.
Closest to 'persistent productivity tax' (b5). The choice applies to both web and cli contexts (wide applies_to scope) and affects every developer who must debug, upgrade, or monitor the application. Wrong error reporting silently hides deprecations and runtime notices, slowing many work streams (debugging, upgrades, security reviews), but it doesn't reshape the entire architecture — b5 fits well.
Closest to 'serious trap' (t7). The misconception field states explicitly that 'setting error_reporting(0) is a valid security measure' — this is a widely-held wrong belief that contradicts how security actually works (hiding != preventing). Developers from other languages may also expect error suppression to be safe by default. This contradicts the principle seen in other ecosystems (e.g. exception-first languages) and is a documented, recurring pitfall, warranting t7.
Also Known As
TL;DR
Explanation
PHP errors span multiple levels: E_ERROR (fatal, stops execution), E_WARNING (non-fatal runtime), E_NOTICE (minor runtime hints), E_DEPRECATED, E_STRICT (coding standards), E_PARSE (compile-time syntax), and the aggregate E_ALL. error_reporting = E_ALL is the correct development setting — it surfaces E_NOTICE and E_DEPRECATED issues that become real bugs. display_errors must be Off in production (log instead). set_error_handler() registers a custom handler to convert errors to exceptions or structured log entries. PHP 8.0 promotes many warnings to TypeErrors, making strict typing even more valuable.
Common Misconception
Why It Matters
Common Mistakes
- Setting error_reporting = 0 in development — hides all errors and makes debugging impossible.
- Not enabling E_DEPRECATED — deprecated function calls are silent until the version that removes them.
- Using display_errors = On in production — leaks file paths, stack traces, and database structure to users.
- Not converting errors to exceptions with set_error_handler() — errors and exceptions get handled inconsistently.
Code Examples
# php.ini — production with errors displayed:
error_reporting = E_ALL
display_errors = On ; Never in production — use log_errors = On instead
log_errors = Off ; Errors not logged — invisible failures
; php.ini — development: show everything
error_reporting = E_ALL
display_errors = On
log_errors = On
; php.ini — production: log, never display
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
display_errors = Off
log_errors = On
error_log = /var/log/php/error.log
// PHP — set at runtime (overrides php.ini)
error_reporting(E_ALL);
set_error_handler(function(int $errno, string $errstr, string $file, int $line): bool {
if (!(error_reporting() & $errno)) return false; // respect @ operator
throw new \ErrorException($errstr, 0, $errno, $file, $line);
});
// Convert all errors to exceptions — makes them catchable and loggable