On my live site visitors see warnings with file paths, and on my local machine I sometimes see a blank white page with no error at all. How should display_errors, error_reporting and logging be set?
DEV3 Developer Forum
How should I configure PHP error reporting for development and production?
Every post is reviewed first. Usually reviewed within 24 hours.
1 reply
A blank page means a fatal error happened while display_errors was off. Visible warnings with paths in production leak information. The solution is different settings per environment.
Development (php.ini or top of script)
display_errors = On
display_startup_errors = On
error_reporting = E_ALL
log_errors = On
Production
display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL
log_errors = On
error_log = /var/log/php/app-error.log
Keep error_reporting = E_ALL in production too and log everything; only the display is turned off. That way you can still find the cause of a 500 page.
Runtime override (when you cannot edit php.ini)
ini_set('display_errors', '0');
ini_set('log_errors', '1');
error_reporting(E_ALL);
For fatal syntax errors in the same file, the ini_set never runs; set values in php.ini, .user.ini or the host control panel.
Convert warnings to exceptions so they are not ignored:
set_error_handler(function (int $no, string $str, string $file, int $line) {
if (!(error_reporting() & $no)) return false;
throw new ErrorException($str, 0, $no, $file, $line);
});
and a last-resort handler:
set_exception_handler(function (Throwable $e) {
error_log((string) $e);
http_response_code(500);
echo 'Something went wrong.';
});
Find the log
php -i | grep error_log or php_ini_loaded_file(); on Apache without error_log set, errors go to the Apache error log; on PHP-FPM check the pool's catch_workers_output setting. cPanel hosts have an error_log file in the script folder.
Pitfalls
- Fatal "Allowed memory size exhausted" and "Maximum execution time" appear only in logs when display is off.
- Notices that became warnings or errors in PHP 8 (undefined variable, undefined array key) are visible with E_ALL.
- Frameworks bring their own handlers (Laravel's
APP_DEBUG); never leave debug true in production.