Debugging PHP functions in WordPress

When developing a plugin or theme, you sometimes want to debug one specific function. This function might be used in a larger context, which makes debugging quite difficult and/or slow. Let’s take the example of a function used in a shortcode (or server side rendered block) for example:

function my_shortcode_callback( $atts ) {
	$atts = shortcode_atts( array(
		'post_id' => '',
		// ...
	), $atts, 'my_shortcode' );

	$result = my_function_to_debug( $atts );

	return sprintf(
		__( 'Posted on %1$s by %2$s', 'my-textdomain' ),
		date_i18n( get_option( 'date_format' ), $result['date'] ),
		get_the_author_meta( 'display_name', $result['author'] )
	);
}
add_shortcode( 'my_shortcode', 'my_shortcode_callback' );

In this callback, we now call the function we want to debug. This function can be simple or very complex. Let’s take this one as an example:

function my_function_to_debug( $atts ) {
	$post = get_post( (int) $atts['post_id'] );
	// Maybe do something with the post and create some result
	// ...

	// Dummy result: select two values from the post
	$result = [
		'date'   => $post->post_date,
		'author' => $post->post_author,
	];

	return $result;
}

If you do this in a normal way, you would have to create a page/post and add the shortcode, so the callback and the function to debug get called. Let’s assume you want to debug the shortcode with a lot of different arguments. Then you have to insert multiple shortcodes on one page/post or even create multiple posts/pages.

Debug using the WP-CLI

One of the methods I’m using to debug such a function is using the WP-CLI. Here you can run code “with a WordPress environment” using the wp shell command. This is how this may look like:

$ wp shell
wp> my_function_to_debug( [ 'post_id' => 1 ] );
=> array(2) {
  ["date"]=>
  string(19) "2021-09-26 21:57:32"
  ["author"]=>
  string(1) "1"
}

After starting the shell, we just call the function and pass the arguments we want to test the function with. As the function returns an array, we get the result with a var_dump visualization.

In the same way we could also debug the shortcode callback, or any other function from any plugin/theme or WordPress core:

$ wp shell
wp> my_shortcode_callback( [ 'post_id' => 1 ] );
=> string(34) "Posted on 5 December 2021 by wapuu"

The benefit of this debugging technique is that it will not have to render a (frontend) page/post. It will “only” load the WordPress environment and then execute the function. This is a done lot faster and easier. You also don’t have to create a page using this shortcode.

Debug the function using an AJAX callback

The only issue with this approach can be, that debugging a function using XDEBUG is not (easily) possible, as XDEBUG usually only works in combination with an HTTP request. You could run such a request on the shell using curl, but then you also have to create a page/post with the shortcode and the arguments. Instead, you can “misuse” an AJAX callback function to execute the function in an HTTP request:

function my_ajax_callback() {
	$result = my_function_to_debug( [ 'post_id' => 1 ] );
	var_dump( $result );
}
add_action( 'wp_ajax_my_ajax_action', 'my_ajax_callback' );

Now you run an HTTP request to the URL /wp-admin/admin-ajax.php?action=my_ajax_action (either in a browser or the terminal) and you will get the same var_dump result. This time tough, you can set breakpoints for your debugging with XDEBUG.

Conclusion

Debugging a function does not always require a huge setup of pages/posts to call functions you want to test. With the help of the amazing WP-CLI or the use of an AJAX callback, this can be done a lot easier and faster.

1 comment » Write a comment

  1. Great post!
    Thank you very much, now I can debug all WP functions trough; wp shell
    Awesome

Leave a Reply

Your email address will not be published. Required fields are marked *