Debug in WordPress

In development, you need to be able to see where the error is when something suddenly breaks. WordPress has a special debug mode for this. In this post, let's take it apart and see what this WP_DEBUG constant is.

Base knowledge

Debug mode is enabled by the WP_DEBUG constant. It is disabled by default - the file wp-config.php has the constant:

define( 'WP_DEBUG', false );

It can be enabled by setting the value of the constant to true:

define( 'WP_DEBUG', true );

true in this case enables processing of absolutely all PHP errors and displaying them on the screen. Also enabling the WP_DEBUG constant activates additional logic in the kernel, plugins and themes code, where the value of this constant is checked and something is done if it is enabled.

Read more about WP_DEBUG below.

Need to know

All debug mode constants are defined in file wp-config.php.

By default, the debug constants have the following values:

  • WP_DEBUG = false (true when 'development' === wp_get_environment_type())
  • WP_DEBUG_DISPLAY = true (it only works when WP_DEBUG is enabled)
  • WP_DEBUG_LOG = false

WP_DEBUG_DISPLAY and WP_DEBUG_LOG are activated only if the WP_DEBUG constant is enabled.

Enabling WP_DEBUG does not change the value of other constants. That is, when WP_DEBUG = true WP_DEBUG_DISPLAY and WP_DEBUG_LOG will retain their default values and PHP settings for error display and logging will be set based on these values.

However, if WP_DEBUG = false, the error display and logging will work based on the settings in the php.ini file.

Use wp_get_environment_type(), to control the development environment.

It is important to disable "debugging" on the working (production) site.

Error display is always disabled for AJAX requests, you can only see errors there through the log file. This is set in wp_debug_mode():

if ( defined( 'XMLRPC_REQUEST' ) || defined( 'REST_REQUEST' ) || ( defined( 'WP_INSTALLING' ) && WP_INSTALLING ) || wp_doing_ajax() ) {
	@ini_set( 'display_errors', 0 );
}

How to enable error display in an AJAX request, see article about AJAX.

Why do we need "debug mode"?

Let's say you changed the functions.php file of the theme and the site stopped working. In its place is a white screen - nothing is clear. "Debug" will help to understand, it will show you the error and tell you in which line of what file it is.

"Debug" displays not only the errors that cause the site to stop working, but also the notes and warnings. Notes can be created by PHP itself (for example, when a variable is used incorrectly) or by PHP script code (for example, WP creates such notes if the site uses a deprecated WordPress function, or an deprecated function parameter).

Examples of enabling Debug mode

Basic enabling

Open the wp-config.php file at the root of your site and change false to true on the line:

define( `WP_DEBUG`, true ); // false - turn off error display

When you turn it on like this:

  • All error levels will be reported in the error report.
  • All errors will be displayed on the screen, because WP_DEBUG_DISPLAY = true by default.
  • Errors will be logged to the log file specified in php.ini, because WP_DEBUG_LOG = false by default.

Enable debug mode and log file, and disable displaying errors

The code below will enable all levels of errors (notice, warning, error) to be written to the wp-content/debug.log file and disable the notice, warning output to the screen.

define( 'WP_DEBUG', true );          // debug mode
define( 'WP_DEBUG_LOG', true );      // error logging to a file /wp-content/debug.log
define( 'WP_DEBUG_DISPLAY', false ); // disables error display

Thanks to the code above, error logging to a file has been enabled. This can be used to write the contents of the variables to log file:

error_log( $value );               // Scalar values
error_log( print_r( $value, 1) );  // Any data

Debug mode for production site

For a production site, it is recommended to specify the following in the wp-config.php file:

define( 'WP_DEBUG', false );
@ini_set( 'display_errors', 0 );
@ini_set( 'log_errors', 1 );

In this setting we force change values from php.ini file for log_errors and display_errors directives, because WP will not set it when WP_DEBUG = false, and we do not trust what is set in php.ini. If we need to leave the values from php.ini, then these ini_set() directives can be omitted.

You can see on the internet that the values of constants are also set:

define( 'WP_DEBUG_DISPLAY', false );
define( 'WP_DEBUG_LOG', false );

However, this setting just doesn't make sense, because WP_DEBUG_DISPLAY simply doesn't work without WP_DEBUG enabled, and WP_DEBUG_LOG already defaults to false.

Dynamically turn on/off errors display

This code helps to quickly enable the WP_DEBUG constant, which on a working site should be turned off. The code also allows you to enable error logging in the /wp-content/debug.log file, and disable error display on the screen.

Why this code is handy? Let's say we made the site and it works, but we periodically fix it's code. While editing of course appear different errors, including fatal ones. To see what the cause, we need to enable debug, to do this, open wp-config.php and change the constant, after completion it is necessary to return everything back. This is inconvenient, it's more convenient to enable debug via URL and see errors when needed.

Enabling errors is saved in the cookie of your site so it will works only for you.

To get things working, replace line define( WP_DEBUG, false ); in file wp-config.php with this code:

GitHub
<?php

/**
 * Dynamically enable/disable the display of PHP errors in WordPress.
 *
 * Installation:
 * replace line 'define( WP_DEBUG, false );' in 'wp-config.php' file with this code.
 *
 * Enabling debug mode:
 * NOTE: Strongly recommended to changing the 'debug' word to something more unique!
 * add the 'debug' query parameter to the URL. Examples:
 * https://site.com/?debug - default enabling of WP_DEBUG constant
 * https://site.com/?debug=1 - logging of errors into file 'DOCUMENT_ROOT/../php-errors-{HOST}.log'.
 * https://site.com/?debug=2 - linking uncompressed scripts and saving all SQL queries to $wpdb->queries
 * https://site.com/?debug=3 - saving all SQL queries in $wpdb->queries
 * https://site.com/?debug=4 - disable displaying errors (enabled by default)
 * https://site.com/?debug=14 - combining
 *
 * Disabling debug mode:
 * https://site.com/?debug=anything
 *
 * @author Kama (http://wp-kama.ru)
 * @version 2.5
 */
// IMPORTANT: change from `debug` to your unique key!
kama_define_wp_debug( 'debug' );

function kama_define_wp_debug( $key ){

	$val = isset( $_GET[ $key ] ) ? ( $_GET[ $key ] ?: 'yes' ) : false;

	// set/delete cookie
	if( $val !== false ){

		$cookie = preg_match( '/^(yes|[1234])$/', $val ) ? $val : null;

		$host = str_replace( 'www.', '', $_SERVER['HTTP_HOST'] );

		// cirilic domains: .сайт, .онлайн, .дети, .ком, .орг, .рус, .укр, .москва, .испытание, .бг
		false !== strpos( $host, 'xn--' )
			? preg_match( '~xn--[^.]+.xn--[^.]+$~', $host, $mm )
			: preg_match( '~[a-z0-9][a-z0-9-]{1,63}.[a-z.]{2,6}$~', $host, $mm );

		$host = $mm[0];

		$_COOKIE[ $key ] = $cookie;
		setcookie( $key, $cookie, time() + ( $cookie ? 3600 * 24 * 365 : -3600 ), '/', ".$host" );
	}

	// enable the debug based on the cookie
	if( ! empty( $_COOKIE[ $key ] ) ){

		define( 'WP_DEBUG', true );

		$set = array_flip(
			preg_split( '/(\d)/', $_COOKIE[ $key ], -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY )
		);

		isset( $set[1] ) && define( 'WP_DEBUG_LOG', dirname( $_SERVER['DOCUMENT_ROOT'] ) . "/php-errors-{$_SERVER['HTTP_HOST']}.log" );
		isset( $set[2] ) && define( 'SCRIPT_DEBUG', true );
		isset( $set[3] ) && define( 'SAVEQUERIES', true );
		isset( $set[4] ) && define( 'WP_DEBUG_DISPLAY', false );
	}
	else {
		define( 'WP_DEBUG', false );
	}
}

Now, to enable WP_DEBUG mode, you need to add ?debugquery parameter to any URL, for example:

  • http://example.com/?debug - enables debug.
  • http://example.com/?debug=1 - forced output to screen if such output is disabled.
  • http://example.com/?debug=2 - logging to file.

For protection, the debug key should be changed to your own key, which only you will know, because you will use it to enable/disable the debug mode.

When enabling error logging (?debug=2) the site parent folder (DOCUMENT_ROOT/..) must be writable, otherwise PHP will not be able to create the log file. Or you can manually create a log file DOCUMENT_ROOT/../php-errors-example.com.log. It must have write permissions (CHMOD 660 or higher).

WP_DEBUG

Default: false.

The WP_DEBUG constant enables or disables debug mode in WordPress.

When debug mode is enabled, absolutely all error levels will be included in the error report. When disabled, only important error levels will be included in the report.

  • When WP_DEBUG = true:

    • for display_errors is responsible the value of the constant WP_DEBUG_DISPLAY.
    • for log_errors and error_log is responsible the value of the constant WP_DEBUG_LOG.
    • And error_reporting is set to E_ALL - to include absolutely all error levels in the report.
  • When WP_DEBUG = false:
    • display_errors, log_errors and error_log, remain as they are specified in the php.ini file.
    • And error_reporting is set to
      E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR

The WP_DEBUG constant should be set in wp-config.php file.

define( 'WP_DEBUG', false ); // debug is disabled. Default.
// or
define( 'WP_DEBUG', true ); // debug enabled

If the WP_DEBUG constant is not set at all in wp-config.php, it defaults to false. However, if the development environment is specified, it defaults to true:

if ( wp_get_development_mode() || 'development' === wp_get_environment_type() ) {
	define( 'WP_DEBUG', true );
} else {
	define( 'WP_DEBUG', false );
}

Note: do not set false in quotes - 'false'. In this case the debug will be enabled because the value of string 'false' is logical true.

PHP errors, warnings and notices

There are different levels of errors in PHP. Without going into details, the significance levels are:

  1. errors - a serious error which leads to a halt of the script. Aborts PHP.
  2. warnings - not an error, but a warning about something. PHP does not interrupt.
  3. notices - not an error, but a note about something. PHP does not interrupt. Notes may indicate possible bugs in the code. Fixing them will usually make the code more stable.

"Debug mode" includes all levels of errors. This is not like PHP's usual behavior: usually only errors at the 'errors' level are included, and warnings and notices are not shown. See error_reporting() for more details.

Deprecated functions, hooks and deprecated function parameters

WP_DEBUG also includes internal WordPress noties. WordPress has special functions like _deprecated_function(), which show a notices level error when an deprecated function or hook or parameter of a hook, function, etc. is used. These notices warn that the WP function is considered deprecated and should be replaced because it can be removed at any time. Such notes most often suggest an alternative function to replace it.

WP_DEBUG_DISPLAY

Default: true

Another WP_DEBUG component, which controls the display of errors.

Depends on WP_DEBUG! Only works if debug is enabled WP_DEBUG = true. Otherwise it just uses the global value of the PHP display_errors option.

If you specify in wp-config.php:

  • define( 'WP_DEBUG_DISPLAY', true ) - (by default) WP will display errors.

  • define( 'WP_DEBUG_DISPLAY', false ) - The errors will not be displayed. This is needed when errors are written to a log file (see WP_DEBUG_LOG) and you can see them later.

  • define( 'WP_DEBUG_DISPLAY', null ) - WP will not specify a value for PHP option display_errors at all, i.e. it will use the global PHP (server) setting.

Error display is always turned off for REST, AJAX or XML-RPC requests. Such code ini_set('display_errors', 0 ) works for those requests forcibly. The value of WP_DEBUG_DISPLAY constant does not change!

WP_DEBUG_LOG

Default: false.

Enables writing errors to a file. Overwrites the following directives specified in the php.ini file:

ini_set( 'log_errors', 1 );
ini_set( 'error_log', WP_CONTENT_DIR . '/debug.log' );

Only works if WP_DEBUG = true. Otherwise directives from php.ini will be used.

Writing errors in the log file can be useful when you want catch errors, which does not display anything on the screen. For example, when AJAX request or when testing CRON or REST.

Example of including error recording in the default log file /wp-content/debug.log:

define( 'WP_DEBUG_LOG', true );

In this case, the default path to the file is used, which is located in the folder accessed via HTTP: https://example.com/wp-content/debug.log. This is not a secure location because anyone can access it.

Ideally, the log file should be located above the root directory to which there is no HTTP access. If for some reason you can't put it above the root directory, then, set 600 permissions on the file and add such an entry to the .htaccess file in the root directory of your WordPress installation:

<Files debug.log>
	Order allow,deny
	Deny from all
</Files>

Example of including error recording in a custom log file

Via WP

With WordPress 5.1, in WP_DEBUG_LOG you can specify a file path where errors will be stored. For example, let's place it one level above the current WORDPRESS installation:

define( 'WP_DEBUG_LOG', dirname( __DIR__ ) . '/errors.log' );
Via PHP

Changing the path via PHP can be useful when WP_DEBUG = false and when you want to change the path specified in the php.ini file.

ini_set( 'error_log', dirname( __DIR__ ) . '/errors.log' );
  • The end folder in the specified path must exist and be writable for PHP.
  • The file inside may not exist, it will be created as soon as the first error occurs.

WP_DISABLE_FATAL_ERROR_HANDLER

По умолчанию: false

Allows you to disable fatal error handling built into WordPress since version 5.2.

When a fatal error occurs on a WordPress site, it sends an email to the administrator.

If for some reason you don't want to send such emails, add this line of code to the wp-config.php file:

define( 'WP_DISABLE_FATAL_ERROR_HANDLER', true );

Since WP 5.2, a class WP_Fatal_Error_Handler{} has been added to the core to handle Fatal Errors. For this purpose, the WP_Fatal_Error_Handler::handle() method is hung on the shutdown event.

The fatal error handler class can be overridden!

To do this, you need to create a file wp-content/fatal-error-handler.php where you need to return the handler object:

<?php
/**
 * File: wp-content/fatal-error-handler.php
 * Substitute for the class: WP_Fatal_Error_Handler()
 */

class My_Fatal_Error_Handler {

	public function handle() {
		// your code here
	}
}

return new My_Fatal_Error_Handler();

As a basis for creating such a class you should take the class WP_Fatal_Error_Handler{}.

See the function code for how this works:

SAVEQUERIES

Default: not set.

Related to debug constant. When enabled, all SQL queries will be saved in the $wpdb->queries property as an array. In this array you can see all SQL queries and if necessary find the right one and make sure it is correct, etc.

In addition to the query itself, also recorded data about how much time the query took and what function it was called.

// save SQL queries and their data in `$wpdb->queries`
define( 'SAVEQUERIES', true );

Important! this option requires additional memory and PHP operations. Therefore, for performance reasons, this constant should be used only while site development.

An example of how you can see all the SQL requests:

if ( current_user_can( 'administrator' ) ) {
	global $wpdb;
	print_r( $wpdb->queries );
}

SCRIPT_DEBUG

Default: false.

A debug-related constant. Controls which JS and CSS files to use: compressed or full. When enabled, WordPress will use uncompressed versions (dev versions) of JS and CSS files. The default is to use min versions of the files. This is necessary for testing when modifying embedded js or css files.

// use full versions of WP `.css` and `.js` files
define( 'SCRIPT_DEBUG', true );

CONCATENATE_SCRIPTS

Default: true.

Allows you to disable script concatenation in the admin. See. script_concat_settings().

To speed up the admin area, all JavaScript files are merged into a single URL. If you work with admin scripts, it is advisable to disable this function:

define( 'CONCATENATE_SCRIPTS', false );

How does Debug mode work?

When generating a page, at the very beginning of WordPress loading (see. wp-settings.php), among others, two functions are triggered:

  • wp_initial_constants() - sets default values of constants if they were not set in the wp-config.php file.

  • wp_debug_mode() - overrides php.ini directive values based on the specified debug constants. Using PHP functions, the following are sets:
    • Which error levels to handle.
    • Whether to display them on the screen or not.
    • Whether to log errors to a file or not.
    • Which file to log errors to.

WP_DEBUG does not work?

Sometimes you may have a situation when you enable WP_DEBUG in wp-config, but the error is still not visible. This behavior can occur when somewhere after the error display settings by WordPress itself, these settings are changed. For example in MU plugin, a regular plugin or in the theme, the errors are turned off by reinstalling the ini directives PHP, something like this code:

error_reporting( 0 ); // turn off error messages
ini_set( 'display_errors', 0 ); // disables displaying errors

In this case WP's debug settings get interrupted and it stops working.

To solve this, it is best to find where the settings are changed and delete such lines, so that from now on you can work only with WP_DEBUG constant.

As another solution, you can try to re-build the error output settings by specifying them again:

error_reporting( E_ALL ); // enable error messages
ini_set( 'display_errors', 1 ); // show errors on the screen

WP functions for debugging

System data

For debugging, WP has a class WP_Debug_Data. For example, using the following method we can get a bunch of data about the system:

require_once ABSPATH . '/wp-admin/includes/class-wp-debug-data.php';
require_once ABSPATH . '/wp-admin/includes/update.php';
require_once ABSPATH . '/wp-admin/includes/misc.php';

$data = WP_Debug_Data::debug_data();

print_r( $data );

We get a big data set:

Array (
	[wp-core] => Array(
			[label] => WordPress
			[fields] => Array(
					[version] => array( data )
					[site_language] => array( data )
					[user_language] => array( data )
					[timezone] => array( data )
					[home_url] => array( data )
					[site_url] => array( data )
					[permalink] => array( data )
					[https_status] => array( data )
					[multisite] => array( data )
					[user_registration] => array( data )
					[blog_public] => array( data )
					[default_comment_status] => array( data )
					[environment_type] => array( data )
					[user_count] => array( data )
					[dotorg_communication] => array( data )
				)
		)

	[wp-paths-sizes] => Array(
			[label] => Directories and Sizes
			[fields] => Array(
					[wordpress_path] => array( data )
					[wordpress_size] => array( data )
					[uploads_path] => array( data )
					[uploads_size] => array( data )
					[themes_path] => array( data )
					[themes_size] => array( data )
					[plugins_path] => array( data )
					[plugins_size] => array( data )
					[database_size] => array( data )
					[total_size] => array( data )
				)
		)

	[wp-dropins] => Array(
			[label] => Drop-ins
			[show_count] => 1
			[description] => Drop-ins are single files, found in the /public_html/assets directory, that replace or enhance WordPress features in ways that are not possible for traditional plugins.
			[fields] => Array(
					[maintenance.php] => array( data )
					[object-cache.php] => array( data )
				)
		)

	[wp-active-theme] => Array(
			[label] => Active Theme
			[fields] => Array(
					[name] => array( data )
					[version] => array( data )
					[author] => array( data )
					[author_website] => array( data )
					[parent_theme] => array( data )
					[theme_features] => array( data )
					[theme_path] => array( data )
					[auto_update] => array( data )
				)
		)

	[wp-parent-theme] => Array(
			[label] => Parent Theme
			[fields] => Array( data )
		)

	[wp-themes-inactive] => Array(
			[label] => Inactive Themes
			[show_count] => 1
			[fields] => Array(
					[Dummy] => array( data )
				)
		)

	[wp-mu-plugins] => Array(
			[label] => Must Use Plugins
			[show_count] => 1
			[fields] => Array(
					[disable-plugins-in-front.php] => array( data )
					[main.php] => array( data )
					[not_support_browsers_redirect.php] => array( data )
					[POMOdoro Translation Cache] => array( data )
					[protect-malicious-queries.php] => array( data )
					[Rus to Lat] => array( data )
				)
		)

	[wp-plugins-active] => Array(
			[label] => Active Plugins
			[show_count] => 1
			[fields] => Array(
					[AJAX Simply] => array( data )
					[Democracy Poll] => array( data )
					[Disable Emojis (GDPR friendly)] => array( data )
					[Display Active Plugins First] => array( data )
					[Kama Breadcrumbs] => array( data )
					[Kama Postviews] => array( data )
					[Kama SpamBlock] => array( data )
					[Kama Thumbnail Pro] => array( data )
					[Redis Object Cache] => array( data )
				)
		)

	[wp-plugins-inactive] => Array(
			[label] => Inactive Plugins
			[show_count] => 1
			[fields] => Array(
					[404 Error Monitor] => array( data )
					[Category Order and Taxonomy Terms Order] => array( data )
					[Contact Form 7] => array( data )
					[Kama Thumbnail] => array( data )
					[Query Monitor] => array( data )
					[Query Monitor Extend] => array( data )
					[Right Now Reloaded] => array( data )
					[Three Column Screen Layout] => array( data )
					[TinyPNG - JPEG, PNG & WebP image compression] => array( data )
					[User Role Editor] => array( data )
					[Widget Logic] => array( data )
					[WooCommerce] => array( data )
					[WordPress Sphinx Search Plugin] => array( data )
					[WP Crontrol] => array( data )
					[WP Super Cache] => array( data )
					[Yoast SEO] => array( data )
				)
		)

	[wp-media] => Array(
			[label] => Media Handling
			[fields] => Array(
					[image_editor] => array( data )
					[imagick_module_version] => array( data )
					[imagemagick_version] => array( data )
					[imagick_version] => array( data )
					[file_uploads] => array( data )
					[post_max_size] => array( data )
					[upload_max_filesize] => array( data )
					[max_effective_size] => array( data )
					[max_file_uploads] => array( data )
					[imagick_limits] => Array ( data )
					[imagemagick_file_formats] => Array( JPEG, JPG, MOV, MP4, MPEG, MPG, PNG, PNG24, WBMP, WEBP, WMV ... )
					[gd_version] => array( data )
					[gd_formats] => array( data )
					[ghostscript_version] => array( data )
				)
		)

	[wp-server] => Array(
			[label] => Server
			[description] => The options shown below relate to your server setup. If changes are required, you may need your web host’s assistance.
			[fields] => Array(
					[server_architecture] => array( data )
					[httpd_software] => array( data )
					[php_version] => array( data )
					[php_sapi] => array( data )
					[max_input_variables] => array( data )
					[time_limit] => array( data )
					[memory_limit] => array( data )
					[max_input_time] => array( data )
					[upload_max_filesize] => array( data )
					[php_post_max_size] => array( data )
					[curl_version] => array( data )
					[suhosin] => array( data )
					[imagick_availability] => array( data )
					[pretty_permalinks] => array( data )
				)
		)

	[wp-database] => Array(
			[label] => Database
			[fields] => Array(
					[extension] => array( data )
					[server_version] => array( data )
					[client_version] => array( data )
					[database_user] => array( data )
					[database_host] => array( data )
					[database_name] => array( data )
					[database_prefix] => array( data )
					[database_charset] => array( data )
					[database_collate] => array( data )
				)
		)

	[wp-constants] => Array(
			[label] => WordPress Constants
			[description] => These settings alter where and how parts of WordPress are loaded.
			[fields] => Array(
					[ABSPATH] => array( data )
					[WP_HOME] => array( data )
					[WP_SITEURL] => array( data )
					[WP_CONTENT_DIR] => array( data )
					[WP_PLUGIN_DIR] => array( data )
					[WP_MEMORY_LIMIT] => array( data )
					[WP_MAX_MEMORY_LIMIT] => array( data )
					[WP_DEBUG] => array( data )
					[WP_DEBUG_DISPLAY] => array( data )
					[WP_DEBUG_LOG] => array( data )
					[SCRIPT_DEBUG] => array( data )
					[WP_CACHE] => array( data )
					[CONCATENATE_SCRIPTS] => array( data )
					[COMPRESS_SCRIPTS] => array( data )
					[COMPRESS_CSS] => array( data )
					[WP_LOCAL_DEV] => array( data )
					[DB_CHARSET] => array( data )
					[DB_COLLATE] => Array()
				)
		)

	[wp-filesystem] => Array(
			[label] => Filesystem Permissions
			[description] => Shows whether WordPress is able to write to the directories it needs access to.
			[fields] => Array(
					[wordpress] => array( data )
					[wp-content] => array( data )
					[uploads] => array( data )
					[plugins] => array( data )
					[themes] => array( data )
					[mu-plugins] => array( data )

				)
		)

)

Customizing php.ini

First of all, the default logging and error display settings are specified in the PHP configuration file php.ini, which you may or may not have access to. If you do have access, you should set them there. It is strongly recommended that you do not display error messages on the working site, but redirect them to the error log file. Also, error log files should not be accessible by URL.

Example of recommended settings for php.ini:

error_reporting = 4339
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /home/example.com/logs/php_error.log
log_errors_max_len = 1024
ignore_repeated_errors = On
ignore_repeated_source = Off
html_errors = Off

error_reporting = 4339 is a custom value. 4339 is the decimal representation of the binary number 100001111110011. Each 1 of the binary value corresponds to an enabled error level, and 0 to a disabled error level.

In the error_reporting value it is more convenient to specify constants rather than numbers, for example:

# Include all types of errors in the report
error_reporting = E_ALL

# Include all error types except E_NOTICE E_STRICT E_DEPRECATED in the report
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED

# Include only the specified error types in the report
error_reporting = E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR

PHP error level table (see [PHP Error Constants](). PHP Error Constants):

Constant decimal binary Description
E_ERROR 1 1 Fatal errors that cannot be fixed by means of the script itself, such as memory allocation error, etc.
E_WARNING 2 10 Warnings. The script is not interrupted.
E_PARSE 4 100 Errors at the compilation stage. Should be generated only by the parser.
E_NOTICE 8 1000 Notices. Potential error in the script. The script is not interrupted.
E_CORE_ERROR 16 10000 Fatal errors. Occurs during PHP startup. Similar to E_ERROR, but generated by the PHP kernel.
E_CORE_WARNING 32 100000 Warnings. Occurs during the initial startup of PHP. Similar to E_WARNING, but generated by the PHP kernel.
E_COMPILE_ERROR 64 1000000 Fatal errors at the compilation stage. Similar to E_ERROR, but generated by Zend engine.
E_COMPILE_WARNING 128 10000000 Warnings at compile time. Similar to E_WARNING, but generated by Zend engine.
E_USER_ERROR 256 100000000 Similar to E_ERROR, only generated by the user in the script code via trigger_error().
E_USER_WARNING 512 1000000000 Similar to E_WARNING, but generated by the user in the script code via trigger_error().
E_USER_NOTICE 1024 10000000000 Similar to E_NOTICE, only generated by the user in the script code via trigger_error().
E_STRICT 2048 100000000000 Included to allow PHP to suggest code changes that will ensure better code interoperability and compatibility.
E_RECOVERABLE_ERROR 4096 1000000000000 Fatal errors with possibility of handling. Indicates that a dangerous situation has occurred, but the script engine is stable. If not handled by a custom function (see set_error_handler()), execution is aborted as for E_ERROR.
E_DEPRECATED 8192 10000000000000 Notices about the use of deprecated constructs. Enabled when you need to warn about code that will not work in future versions of PHP.
E_USER_DEPRECATED 16384 100000000000000 Similar to E_DEPRECATED, only generated by the user via trigger_error().
E_ALL 32767 111111111111111 All supported bugs, warnings, and comments.

The bit representation of a constant can be viewed like this:

$err_lvl = E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE;
var_dump( $err_lvl ); // int(119)
var_dump( decbin( $err_lvl ) ); // string(7) "1110111"

IMPORTANT: WordPress always changes the error_reporting value specified in the php.ini file via the error_reporting() function. This is done in the wp_debug_mode() function.

If WP_DEBUG = true, absolutely all error levels are included in the report:

error_reporting( E_ALL );

When WP_DEBUG = false, the report includes this list of errors:

error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR );

Plugins for debugging and profiling in WordPress

There are several plugins in the WP catalog that extend the "debugging" capabilities and provide additional information to identify code weaknesses. Popular ones are:

  • Query Monitor - displays a bunch of useful information about the current page query. How much time was spent, how many SQL queries, what queries, how long each query took, how much memory was spent, what hooks were used, etc.

  • Query Monitor Addons