PHP hides errors by default. On a production server this is correct behavior – you do not want stack traces, file paths, and database connection details displayed to visitors. But during development or when debugging a broken site, hidden errors make it impossible to figure out what went wrong. You see a blank white page or unexpected behavior with no indication of the cause.
This guide covers how to enable PHP error display and reporting, what the different error levels mean, how to configure this in php.ini and in WordPress specifically, and when you should display errors versus log them to a file.
Why PHP hides errors by default#
PHP’s default configuration sets
display_errors
to
Off
and
error_reporting
to a level that suppresses notices and deprecation warnings. This is a security measure. PHP errors often expose internal details about your application:
- File paths on the server filesystem
- Database table names and query fragments
- Function arguments that may contain sensitive data
- The PHP version and loaded extensions
On a public-facing site, this information helps attackers. A stack trace that reveals
/var/www/html/wp-content/plugins/vulnerable-plugin/includes/db.php on line 47
tells an attacker exactly where to look. The default configuration prevents this by keeping errors internal.
The problem is that the same configuration that protects production makes development and debugging painful. When something breaks, you need to see what PHP is complaining about. The solution is to enable error display in development and log errors to a file in production.
PHP error levels#
PHP categorizes errors by severity. Each level has a constant you can use in configuration.
| Constant | What it means |
|---|---|
E_ERROR
| Fatal error. Script execution stops. Missing required files, calling undefined functions, out of memory. |
E_WARNING
| Non-fatal runtime warning. Script continues executing. Common examples: failed file operations, incorrect function arguments. |
E_NOTICE
| Minor issue. Accessing an undefined variable, using a string offset as an array. |
E_PARSE
| Syntax error. The script cannot be compiled at all. Missing semicolons, unmatched brackets. |
E_DEPRECATED
| Code that works now but uses features scheduled for removal in a future PHP version. |
E_STRICT
| Suggestions for code changes to ensure forward compatibility (largely merged into other levels in PHP 8+). |
E_ALL
| All errors and warnings. Every category above combined. |
In practice, you almost always want
E_ALL
during development. It catches everything, including minor issues that can become real problems later.
Enabling error display in php.ini#
The php.ini file is the primary configuration file for PHP. The two directives that control error visibility are
display_errors
and
error_reporting
.
Find your php.ini location
From the command line:
php --ini
This prints the path to the active php.ini file. On most Linux systems it is something like
/etc/php/8.2/fpm/php.ini
for PHP-FPM or
/etc/php/8.2/cli/php.ini
for command line PHP. Note that PHP-FPM and CLI often use different php.ini files – changes to the CLI config do not affect your web server.
You can also check from a PHP script:
<?php
phpinfo();
The “Loaded Configuration File” line shows the active php.ini path.
Enable display_errors
Open php.ini and find the
display_errors
directive:
display_errors = On
This makes PHP output errors directly in the browser. Set it to
On
for development,
Off
for production.
Set error_reporting level
In the same file, set the reporting level:
error_reporting = E_ALL
E_ALL
reports every category of error. For production, a common setting is:
error_reporting = E_ALL & ~E_DEPRECATED & ~E_NOTICE
This reports all errors except deprecation notices and minor notices – things that indicate code quality issues but do not affect functionality.
Restart PHP-FPM
After changing php.ini, restart PHP-FPM for the changes to take effect:
sudo systemctl restart php8.2-fpm
Replace
8.2
with your PHP version. If you are running PHP as an Apache module instead of PHP-FPM, restart Apache:
sudo systemctl restart apache2
Enabling errors at runtime with ini_set()#
If you cannot edit php.ini (common on shared hosting), you can enable error display from within your PHP script:
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
Place this at the very top of the script, before any other code. These settings apply only to the current script execution – they do not change the server-wide configuration.
There is one limitation:
ini_set()
runs after PHP has already started parsing the script. If the error is a parse error (syntax error), PHP cannot execute the
ini_set()
call because it cannot parse the file at all. For parse errors, you need either php.ini configuration or the command line.
Check for syntax errors from the command line
To catch parse errors without a browser:
php -l yourfile.php
The
-l
flag checks syntax without executing the script. If there is a parse error, it prints the line number. If the syntax is valid, it prints “No syntax errors detected.”
Enabling errors in WordPress#
WordPress has its own error configuration that sits on top of PHP’s settings. The constants are defined in
wp-config.php
.
Enable WP_DEBUG
Open
wp-config.php
(in your WordPress root directory) and add or modify these lines. They must appear before the line that says
/* That's all, stop editing! */
:
define('WP_DEBUG', true);
define('WP_DEBUG_DISPLAY', true);
define('WP_DEBUG_LOG', true);
What each constant does:
| Constant | Effect |
|---|---|
WP_DEBUG
| Master switch. Enables WordPress debug mode and sets
error_reporting
to
E_ALL
. |
WP_DEBUG_DISPLAY
| Controls whether errors are shown in the browser. Set to
true
for development,
false
for production. |
WP_DEBUG_LOG
| Writes all errors to
wp-content/debug.log
. Works independently of display – you can log without displaying. |
Development configuration
For active development or debugging a broken site:
define('WP_DEBUG', true);
define('WP_DEBUG_DISPLAY', true);
define('WP_DEBUG_LOG', true);
Errors appear in the browser and are written to
wp-content/debug.log
.
Production configuration
For a live site where you want to catch errors without exposing them to visitors:
define('WP_DEBUG', true);
define('WP_DEBUG_DISPLAY', false);
define('WP_DEBUG_LOG', true);
Errors are written to the log file but not displayed in the browser. This is the right approach for tracking down intermittent issues on a production site without exposing internal details to visitors.
Disable debug mode entirely
The WordPress default:
define('WP_DEBUG', false);
When
WP_DEBUG
is
false
,
WP_DEBUG_DISPLAY
and
WP_DEBUG_LOG
are both ignored.
Reading the debug log
The log file is at
wp-content/debug.log
. View it via SSH:
tail -100 /var/www/html/wp-content/debug.log
Or follow it in real time while you reproduce the issue:
tail -f /var/www/html/wp-content/debug.log
This streams new log entries as they are written. Press Ctrl+C to stop.
display_errors vs log_errors#
These two directives serve different purposes and can be configured independently.
display_errors outputs error messages directly in the HTTP response. The visitor sees them in the browser. This is useful during development but dangerous in production because it exposes internal information.
log_errors writes error messages to a log file on the server. The visitor sees nothing. You read the errors from the log file when you need to debug.
The recommended configuration:
| Environment | display_errors | log_errors | error_reporting |
|---|---|---|---|
| Development | On | On | E_ALL |
| Production | Off | On | E_ALL & ~E_DEPRECATED & ~E_NOTICE |
On production, always keep
log_errors
on. Errors that nobody ever sees are errors that never get fixed. The log file captures them silently so you can review them on your own schedule.
To configure log_errors and set a custom log file path in php.ini:
log_errors = On
error_log = /var/log/php/error.log
Make sure the directory exists and is writable by the PHP process.
Common scenarios#
White screen of death in WordPress
A completely blank white page usually means a fatal PHP error with
display_errors
off. The error happened, PHP stopped executing, but nothing was shown to the browser.
To diagnose:
- Enable
WP_DEBUGandWP_DEBUG_DISPLAYin wp-config.php - Reload the page
- The error message should now appear, telling you which file and line caused the problem
If editing wp-config.php is not possible (because the error is in wp-config.php itself), check the PHP error log directly. On most systems:
tail -50 /var/log/php/error.log
“Headers already sent” warning
Warning: Cannot modify header information - headers already sent by (output started at /path/to/file.php:1)
This means PHP tried to send HTTP headers after content was already output to the browser. Common causes: a space or blank line before
<?php
in a file, a UTF-8 BOM (byte order mark) at the start of a file, or an
echo
/
print
statement before a
header()
or
setcookie()
call.
The error message tells you exactly which file and line started the output. Check that line for whitespace or unexpected output.
“Allowed memory size exhausted”
Fatal error: Allowed memory size of 134217728 bytes exhausted
PHP hit its memory limit. The default is 128 MB. In php.ini:
memory_limit = 256M
In WordPress, you can also set it in wp-config.php:
define('WP_MEMORY_LIMIT', '256M');
If a script is genuinely consuming hundreds of megabytes, increasing the limit is treating the symptom. The script likely has a memory leak, an unbounded query, or is loading a dataset that should be processed in chunks.
Deprecated function warnings after PHP upgrade
After upgrading PHP, you may see deprecation notices from plugins or themes:
Deprecated: Function create_function() is deprecated in /path/to/plugin/file.php on line 42
These are warnings, not errors. The code still works on the current PHP version but uses features that will be removed in a future version. The fix is to update the plugin or theme. If no update is available, you can suppress deprecation notices specifically:
error_reporting = E_ALL & ~E_DEPRECATED
This is a reasonable production setting. In development, keep
E_ALL
so you see everything.
Error display on Hostney#
On Hostney, PHP configuration including
display_errors
and
error_reporting
is manageable through the control panel without editing php.ini directly.
Go to Hosting > PHP Manager > Variables tab. From there you can set:
- display_errors – toggle error display on or off
- error_reporting – set the reporting level
- log_errors – enable or disable logging
- memory_limit – adjust the PHP memory limit
Changes take effect immediately without needing to restart PHP manually.
PHP error logs are available under Logs & Statistics > PHP Logs in the control panel. For Nginx error logs, see Logs & Statistics > Error Log. See the access and error logs knowledge base page for details on reading and interpreting log output.