PHP 8.0 error_reporting default shift: balancing production alert signal against log noise
0 reputation · 16 Jul 2024, 00:00 UTC
0 reputation · 16 Jul 2024, 00:00 UTC
Since PHP 8.0 the engine defaults error_reporting to E_ALL (32767) instead of the quieter E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED (22527) used through PHP 7.4. The change is documented in the 8.0 migration guide but comes without a prescribed production baseline.
Teams upgrading legacy codebases or running raw PHP scripts in containers need a single error_reporting value that surfaces actionable problems — undefined variables, deprecated library calls — while keeping log aggregators from drowning in notice-level chatter. Frameworks such as Laravel and Symfony set their own level at bootstrap, yet early-boot errors and non-framework entry points still inherit the engine default. Shared hosting and read-only filesystem environments may block php.ini overrides, forcing reliance on ini_set() which misses startup diagnostics. Lowering the level too aggressively risks hiding genuine bugs; leaving it at E_ALL floods stdout/syslog in containerized deployments.
error_reporting bitmask do you consider the pragmatic production default for PHP 8.0–8.3, and how do you justify the excluded categories?php.ini?For PHP 8.0 through 8.3, the pragmatic production default is E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED, which evaluates to the integer 8191. This keeps E_ERROR, E_WARNING, E_PARSE, E_NOTICE, and core/compile diagnostics active while silencing deprecation notices. The rationale is that deprecation messages describe upgrade debt, not live runtime failures; they belong in a scheduled cleanup queue, not in production alert streams. E_STRICT is largely inert in PHP 8.0+ because most strict standards were reclassified in earlier versions, so excluding it has minimal practical effect.
Do not exclude E_NOTICE unless you have instrumented the application to catch those conditions another way. In PHP 8.0 many former notice-level conditions were promoted to warnings, and both classes can expose real logic bugs such as undefined array keys or property accesses.
Because ini_set() runs after engine initialization, it cannot affect parse errors or startup warnings. Use a layered approach:
php.ini during build so startup diagnostics follow the intended level.auto_prepend_file pointing to a bootstrap that calls ini_set('error_reporting', 8191). This covers per-request execution but not pre-startup failures.php -d error_reporting=8191. If scripts are scattered, a shared wrapper or image-level setting is more reliable than per-script flags..user.ini is honored by CGI/FPM only, respects user_ini.cache_ttl (default 300 seconds), and is ignored by CLI. Treat it as a partial fallback, not a universal control.Frameworks such as Laravel and Symfony set their own error handlers at bootstrap and may reset error_reporting. The engine-level value governs non-framework entry points, early-boot code, and CLI scripts that do not load the framework kernel.
Validate the baseline by separating severity classes rather than watching a single aggregate count:
| Severity class | Action |
|---|---|
E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR | Page immediately |
E_WARNING, E_RECOVERABLE_ERROR | Trend as leading indicators |
E_DEPRECATED, E_USER_DEPRECATED | Track volume separately as scheduled cleanup debt |
E_NOTICE | Alert on per-endpoint rate spikes, not raw volume |
Compare log volume per severity and per-endpoint error rate before and after the change over a fixed traffic window. If E_WARNING volume drops to zero, the level may be too restrictive; if E_DEPRECATED dominates the stream, the level is too permissive for your current codebase.
Confirm the effective value in each SAPI context:
php -r 'echo ini_get("error_reporting");'
Create a temporary script that triggers an E_NOTICE, an E_DEPRECATED, and an E_WARNING, then inspect the output or log destination to confirm which severities are captured. In FPM, check the active value with a phpinfo() page or by logging ini_get('error_reporting') at boot.
Are your raw PHP entry points invoked through a single CLI wrapper, or scattered across independent cron jobs and one-off containers? If they are centralized, a single php -d flag or wrapper script is sufficient; if they are scattered, an image-level php.ini or auto_prepend_file is the only reliable enforcement point.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.