WP Development

The following are some techniques I use nearly every day for debugging WordPress and WooCommerce, and can be used for plugin or theme development equally.

Echoing or printing to the screen will only get you so far when debugging, especially in a complex framework like WordPress; to really understand the code flow, and to trace and fix issues, you need to be able to log messages to a file. For this WordPress makes use of the PHP core error_log() function, which allows you to “send an error message somewhere.” Using it is quite simple:

error_log( "Hello World!" );

Put this into a script, request the page and we will have logged a message “somewhere”, but where? By default when running under Apache and called with no additional arguments, error_log() will send the message to your apache error log file. For me this is found at /var/log/apache2/error_log, for you this may be somewhere else, and is specified by your apache conf file. My Apache conf is found at /etc/apache2/httpd.conf, again yours could be elsewhere on your system depending on how you installed Apache. Logging to the apache error log is a good first step, however a lot of stuff that we don’t necessarily care about also gets logged there, and it doesn’t always work well with newlines in your debug statements; thankfully WordPress provides a solution with a set of debugging constants.

Debugging with WP_DEBUG

The first and most important constant is WP_DEBUG. Enable this within your wp-config.php file to report all PHP notices to your log file, and allow the use of the other debugging constants:

define( 'WP_DEBUG', true );

WordPress recommends “that plugin and theme developers use WP_DEBUG in their development environments”, which is indeed good advice, but unfortunately not followed by all developers, which means that your log file can become inundated with notices from misbehaving 3rd party plugins and themes, making it all but impossible to watch for notices from your own plugin development. You don’t have many options here:

  • You can take the time to fix the notices in the offending code (which is nice until you update and get the notice-ridden code all over again)
  • You can deactivate the plugin if you don’t really need it (not always an option)
  • Or you can disable notice reporting (useful if you just want to be able to log debug statements without losing them among notices you don’t care about). Unfortunately this makes it difficult to stay on top of notices from your own plugin development and can make you part of the problem! Still, it’s the best option at times, see my debug helper plugin for a simple way to do this.

A Better Log File With WP_DEBUG_LOG

Enabling the WP_DEBUG_LOG constant, in the same manner as the WP_DEBUG above improves our debugging experience by sending notices and messages to wp-content/debug.log. Another benefit is being able to use the print_r(), var_dump() and other handy multiline debugging functions. WP_DEBUG must be enabled for this constant to have any effect:

define( 'WP_DEBUG',     true );
define( 'WP_DEBUG_LOG', true );

Watch the log file like any other for convenience while developing:

$ tail -f wp-content/debug.log

Remember: One thing to keep in mind with this configuration enabled is that there will be some spots in the WordPress code that are executed prior to the log file being set, so depending on how deeply you’re debugging into core files, you may need to watch the apache error log (or other location, as always depending on your php.ini) for some of your messages. It doesn’t come up often, but if you’re deep into core territory and start missing statements that you know should be logged, check your apache error log, or other default destination before you accuse the computer of cheating.

In Your Face Debugging With WP_DEBUG_DISPLAY

Enabling the WP_DEBUG_DISPLAY constant will cause notices/errors to be displayed right on the page when they occur. When you have all outstanding notices fixed and are developing a plugin or theme this is a great constant to have enabled as it doesn’t require watching your log file. Granted it won’t catch all notices all the time so you will still need to be aware of your log file, but this is a great way to keep yourself honest.

Script Debugging with SCRIPT_DEBUG

By default WordPress will use minified CSS/JavaScript files, which is great for site performance, but not so great for finding and fixing issues with them. Sure you could learn to read minified JavaScript, or you could use yet another handy constant: SCRIPT_DEBUG, which will cause the un-minified scripts to be loaded instead.

Query Debugging With SAVEQUERIES

WordPress is obviously heavily dependent on the database, and this is an area that can be difficult at times to get visibility into. One solution is to enable the SAVEQUERIES constant, which will save all queries to the queries member of the db object along with their execution time, and the stack of functions that called them. I find this one to be of limited benefit just due to the sheer number of database queries in the typical WordPress page load, and I prefer to error_log() the particular query that I’m actually interested in, but it certainly can be useful:

global $wpdb;

error_log( print_r( $wpdb->queries, true ) );

// try and narrow down a particular query:
foreach ( $wpdb->queries as $query ) {
  if ( strpos( $query[2], 'WP_Query->get_posts' ) !== false ) error_log( print_r( $query, true ) );
}

A Plugin to Help with Debuggin’

One of the first plugins I wrote for myself is a small debug helper plugin unimaginatively called WP Debug Helper. This can disable notice reporting for those times when you just can’t deal (this functionality commented-out by default), and adds two functions that I find useful additions to my debugging toolbox:

wp_debug_backtrace()
Convenience function for printing a stack trace
wp_var_dump()
Convenience function for calling the core var_dump() function

Feel free to download it, use it, add to it; let me know in the comments if you have suggestions for any other helpful functions to add.

Putting it all Together

To put it all together and wrap things up, here are some example logging patterns I find myself using over and over:

Configure wp-config.php:

/**
 * For developers: WordPress debugging mode.
 *
 * Change this to true to enable the display of notices during development.
 * It is strongly recommended that plugin and theme developers use WP_DEBUG
 * in their development environments.
 */
define( 'WP_DEBUG',        true );
define( 'WP_DEBUG_LOG',    true );
define( 'WP_DEBUG_DISPLAY',true );
define( 'SCRIPT_DEBUG',    true );
define( 'SAVEQUERIES',     true );

Watch the Log File:

$ tail -f wp-content/debug.log

Example log statement:

error_log( "Hello World!" );

Example logging print_r:

error_log( print_r( $foo, true ) );

Get the classname of an unknown object:

error_log( get_class( $obj ) );

Example logging a stacktrace (if my WP Debug Helper plugin is installed and active):

error_log( wp_debug_backtrace() );

Example var dumping a variable (if my WP Debug Helper plugin is installed and active):

error_log( wp_var_dump( $foo ) );

Dump all defined constants (note that this will be quite extensive within WordPress):

error_log( print_r( get_defined_constants(), true ) );

Dump all available globals (note that this will be quite extensive within WordPress):

error_log( print_r( $GLOBALS, true ) );

// or maybe:
foreach( $GLOBALS as $key => $value ) {
  if ( ! in_array( $key,array( '_wp_using_ext_object_cache', 'wpdb', 'registered' ) ) )
    error_log( $key . " => " . print_r( $value, true ) );
}

Dump queries:

global $wpdb;

error_log( print_r( $wpdb->queries, true ) );

Have any other tips or patterns you find yourself using again and again? Let us know in the comments below. Happy Debugging!

Published by Nik McLaughlin

You can find Nik around the WP space, on LinkedIn, or on his personal blog.

3 Comments

  1. Hello Justin,
    This is a great post, i needed this instustions to customize a complex plugin i purchased.
    I will surely tryout your plugin!.

  2. Very helpful summary, thanks.
    I find that sometimes a debug.log file contains a stack trace, and sometimes just a notice. Is there a switch somewhere to turn on the stack trace?

Hmm, looks like this article is quite old! Its content may be outdated, so comments are now closed.