Error Reporting & Display
debt(d7/e3/b5/t7)
Closest to 'only careful code review or runtime testing' (d7). The term's detection_hints.tools field is not specified. Misconfigured error_reporting or display_errors settings produce no compile-time or linter feedback — the misconfiguration is silent until a developer notices missing error output in development or accidentally exposed stack traces in production. A code review or environment audit is the primary discovery mechanism; no standard default tooling catches it automatically.
Closest to 'simple parameterised fix (replace pattern with safer alternative)' (e3). The quick_fix shows a small set of ini_set() and error_reporting() calls — two to three lines per environment. While the fix itself is trivial, it may need to be applied in multiple places (php.ini, .htaccess, bootstrap files, environment configs) making it slightly more than a single-line patch but well within one component.
Closest to 'persistent productivity tax' (b5). The choice applies to both web and CLI contexts across all PHP versions from 4.0 onward. Misconfigured settings persistently slow debugging (display_errors off in dev) or introduce ongoing security exposure (display_errors on in prod). It affects every developer touching the codebase and every environment, but it doesn't architecturally reshape the system — it's a cross-cutting configuration tax rather than a structural constraint.
Closest to 'serious trap (contradicts how a similar concept works elsewhere)' (t7). The misconception field captures the core trap precisely: developers believe E_ALL and E_NOTICE are noise that breaks working code, when in fact they reveal real latent bugs. Additionally, the @ suppression operator appears to fix errors but silently allows incorrect behaviour to continue. The dual-environment trap (display_errors on in dev, off in prod) also catches many developers. These are non-obvious, widely held wrong beliefs about the concept's correct usage.
Also Known As
TL;DR
Explanation
PHP has two distinct error controls: error_reporting sets which error types PHP generates (E_ALL includes all errors, warnings, notices, and deprecations); display_errors controls whether errors are output to the browser or CLI. The correct configuration differs by environment: Development — error_reporting(E_ALL), display_errors=On, display_startup_errors=On (see all errors immediately). Production — error_reporting(E_ALL), display_errors=Off, log_errors=On (log everything, show nothing to users). The E_ALL level includes E_NOTICE (undefined variables, array access), E_DEPRECATED (functions removed in future PHP versions), E_STRICT (code that may not be forward compatible), and E_WARNING. Setting error_reporting to E_ALL in development and fixing all notices prevents surprises when PHP version upgrades promote notices to errors. The @ error suppression operator silences individual expressions — a code smell that hides problems rather than fixing them.
Common Misconception
Why It Matters
Common Mistakes
- Using error_reporting(0) or @ suppression to hide errors instead of fixing them — suppressed errors still occur and cause incorrect behaviour.
- Setting display_errors=Off in development — makes debugging significantly harder; always show errors in development.
- Not setting display_errors=Off in production — raw PHP errors expose sensitive information to users and attackers.
- Checking for E_ALL without including custom error handlers — set_error_handler() captures errors that PHP would normally display; use it to log and handle errors programmatically.
Code Examples
// Suppressing instead of fixing
$result = @file_get_contents($url); // hides errors
if (!$result) { /* why did this fail? no idea */ }
// Wrong production config
display_errors = On ; php.ini — shows errors to users
error_reporting = E_ERROR ; misses warnings and notices
// Development: show everything
if (getenv('APP_ENV') === 'development') {
error_reporting(E_ALL);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
}
// Production: log everything, show nothing
if (getenv('APP_ENV') === 'production') {
error_reporting(E_ALL);
ini_set('display_errors', '0');
ini_set('log_errors', '1');
ini_set('error_log', '/var/log/php/app-errors.log');
}
// Fix instead of suppress
try {
$result = file_get_contents($url);
if ($result === false) throw new RuntimeException('Failed to fetch: ' . $url);
} catch (RuntimeException $e) {
$this->logger->error($e->getMessage());
}