How to Debug WordPress Beyond the Basics

Debugging WordPress starts with WP_DEBUG, but can go far beyond that. In this article, we will:

  1. See how to write debug messages to a log file and where that file is located
  2. Learn how to use the un-minified JavaScript and CSS core files for debugging purposes,
  3. Learn how to log all the SQL queries run on a page,
  4. Get to know a few plugins that enhance the debugging experience

Writing Debug Messages to a Log File

To start debugging, go to the wp-config.php file in the root of the WordPress file system and turn on the debug variable, i.e., set debug to true:

define( 'WP_DEBUG', true );

Defining this constant as true will cause all PHP errors, notices, and warnings to be displayed on the screen. Doing this during the development phase of the project is highly recommended since it shows you the bugs in your code while you’re developing, and you can fix them right away.

But what if you want to check errors on a production site? Displaying errors on the screen is the last thing you want to do, since it not only disturbs the site’s appearance, it can also be a source of information leak.

So how can we catch bugs that happen in production? Is there a way to see the debug info without sharing it with the site visitors? Indeed there is, and that’s where other constants defined in wp-config.php come into play.

Introduction to WP_DEBUG_DISPLAY and WP_DEBUG_LOG

The WordPress Codex documents a solution to this problem, under the entry How to debug WordPress:

After turning on WP_DEBUG, turn on WP_DEBUG_LOG. That way, the tracked errors are written to a log file.
Now you might ask yourself who’s going to create that log file and where will it reside? The answer is that WordPress takes care of this for us, i.e., no need for our manual creation: as soon as an error comes up, a log file is created, and is placed in the wp-content folder. So simple!

The next thing to do is not to allow errors to be written on the screen. To do this, turn off WP_DEBUG_DISPLAY.

// Disable display of errors and warnings 
define('WP_DEBUG_DISPLAY', false);

And so, the set of commands that enables us to send error messages to a file and not to the screen is this:

 // Enable WP_DEBUG mode
define('WP_DEBUG', true);

// Enable Debug logging to the /wp-content/debug.log file
define('WP_DEBUG_LOG', true);

// Disable display of errors and warnings 
define('WP_DEBUG_DISPLAY', false);

You sometimes might need to add this line in order to hide the errors from the screen. This could happen if the server’s php.ini file has display_errors set to 1.

@ini_set('display_errors',0);

Writing Your Own Messages to the Log File, or When echo Doesn’t Cut it

During the process of locating an error, one of the most convenient ways to debug is by using echo and var_dump. But, sometimes, these commands cannot be used. Sometimes the reason is clear – for example when creating a widget and something goes wrong during the save method, echo to the screen won’t work because the function uses AJAX, thus refreshing the part of the widget to which you’d be echo-ing… Other times, the reason might be unclear – you just get some fatal error that does not allow the page to render, and your echo just doesn’t show up on the screen… Either way, whether the reason is clear or not, the result is the same and you must find a different way to display values of the variables in question.

The solution is turning on both wp_debug and wp_debug_log in wp-config.php, – i.e., setting them both to true.
This creates an error.log file and places it in the wp-content folder .

How to Log Variables Instead of echo

Now, instead of using the echo command to log your variables, you use the error_log PHP command.

So, instead of

echo "I'm on line 38";

You write:

error_log("I'm on line 38");

How to Log Variables Instead of var_dump

Now suppose we do not have an error string or any string at all, but we want to check the values of certain variables, as we do with var_dump.
I found this code snippet a few years ago in a post that explained how to dump var_dump into a file, and it goes like this:

$x = "My string";
// Dump x, or any other variable for that matter
ob_start();
var_dump($x);
$contents = ob_get_contents();
ob_end_clean();
error_log($contents);

Turning our Clever Debugger into a Function

In order not to have to write these 8 lines every time, it’s most effective is to make it a permanent function in your functions.php theme file if you’re developing a theme, or in one of your plugin files if you’re developing a plugin. The function should accept a parameter which is the variable that should be dumped into the file.

Additional error_log Parameters

If you look into the error_log command you’ll see that it gets 3 more optional parameters. The combination of the second one, $message_type, and the third, $destination, and in some cases the fourth, $extra_headers, define additional location to which the error log can be written.

More Debug Possibilities in WP-CONFIG.PHP

SCRIPT_DEBUG

Sometimes – not often – you might have a problem with JS or CSS files that belong to WordPress core, and you’d like to debug them – insert some console.log commands or some other form of debugging,

But WordPress is very efficient in loading its scripts and styles and uses minified versions of the JS and CSS files, but those are challenging to debug.

Fortunately, WordPress is well equipped for such cases and ships an unminified version of every JS and CSS file. The way to tell WordPress to use those files is by turning on the SCRIPT_DEBUG constant in wp-config.php, i.e., set it to true. This forces WordPress to use the “dev” versions of core CSS and JavaScript files rather than the minified versions that are normally loaded.

define('SCRIPT_DEBUG', true);

SAVEQUERIES

There are times when you might want to debug database queries. This could happen either because you suspect one of the queries is taking longer than it should, or it’s returning the wrong results, or any other reason to which the solution would be to look at the queries running on the page you’re loading.
In such a case, turn on the SAVEQUERIES constant in wp-config.php, and all the queries will be saved, in addition to information on how long that query took to execute, and what function called it. All this data is stored in the global $wpdb->queries.

define('SAVEQUERIES', true);

Debugging Plugins

In addition to the built-in ways that WordPress enables you to debug, there are a few plugins that can help with your debugging too. They give much more information than the built-in possibilities and display them in a more sophisticated way. These are the top ones, with their descriptions taken from their plugin page in the WP plugin repository.

  1. Query Monitor
    Description: Query Monitor is the developer tools panel for WordPress. It enables debugging of database queries, PHP errors, hooks and actions, block editor blocks, enqueued scripts and stylesheets, HTTP API calls, Ajax calls, REST API calls, and more. It presents its information in a useful manner, for example by showing aggregate database queries grouped by the plugins, themes, or functions that are responsible for them. It adds an admin toolbar menu showing an overview of the current page, with complete debugging information shown in panels.
    Other information: This plugin has the highest number of active installations (100,000+ at the time of writing this) and is well supported (11 out of 15 issues resolved in the last two months). It has 5 stars based on 363 reviews.
    It’s developed by John Blackbourn, a long time core contributor.
  2. Debug Bar
    Description: Adds a debug menu to the admin bar that shows query, cache, and other helpful debugging information.
    When WP_DEBUG is enabled it also tracks PHP Warnings and Notices to make them easier to find. When SAVEQUERIES is enabled the MySQL queries are tracked and displayed.
    It also has other add-ons available, such as the Debug Bar Console plugin that adds a PHP/MySQL console.
    Other information: This plugin has 30,000+ active installations. Its support is somewhat lacking, with 0 out of 4 issues resolved in the last two months. It has 4 stars based on 59 reviews.
    It’s developed by more than 10 contributors & developers, one of them being WordPress.org, and some of the others are long time core contributors.
  3. Debug This
    Description: Debug This provides information about your WordPress installation, all from the front-end admin bar: The current WP_Query object, Blog info and options, Embed providers, Files in rendered HTML (CSS, images, JavaScript), Filters and actions, Images sizes, Globals and constants, Menus, Object cache stats, Plugins, must-use plugins, dropins, Rewrite rules, Queries, PHP and server information, Post attachments, Post types, Scripts and styles enqueued, Shortcodes, Sidebars and widgets, Taxonomies and terms, Themes, Users, WP Cron schedules and jobs, and WP debug log.
    It enables extensions of its capabilities by adding code. Snippets can be found on the plugin page in the repository.
    Other information: This plugin has 5000+ active installations. There are no issues in the support forum in the past year and a half. It has 4.5 stars based on 15 reviews.
    it’s developed by 4 developers, who are long time plugin and theme developers.

Rubber Duck and Reptilian Brain Debugging

Debugging entails more than just turning on variables. You actually should first try to pinpoint where your error is coming from. In A Guide to Debugging in WordPress with your Reptilian Brain, Fred walks through the different system elements that might be the source of the bug, and when to suspect any of them.

And what if the error is in code you wrote but you can’t find it? In that case, maybe Rubber Duck Debugging, which David explains in detail, can help.

Where To Go Next in Debugging?

I hope this article has introduced something new into your debugging arsenal. It’s powerful to learn how to find what’s gone wrong in WordPress, and I wish you great fortune on that journey.

If you have suggestions for other great debugging tools and techniques, I’d love to hear them in the comments. 🙂


2 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Richard
February 5, 2021 12:29 am

Nice article!

You can also, in the wp-config file, reduce the scope of the debug information with a test, which is based on your IP address (to be replaced by your current address of course).

Something like that:

if (“123.45.67.89” === $_SERVER[“REMOTE_ADDR”]) {
define( ‘WP_DEBUG’, true );
} else {
define( ‘WP_DEBUG’, false );
}

This reduces harmful displays on a production site (while still using the other methods mentioned)

David Hayes
February 11, 2021 11:49 am
Reply to  Richard

Cool idea! I’d genuinely never thought of “only show to my IP” type of debug rules 🙂