Up Periscope: Practical Uses of print_r() in WordPress Development

By default, you can’t look directly at PHP processing, only at its effects.
A persistent need in programming is to know exactly what’s going on with your code. This can be especially tricky in WordPress, for at least three reasons:
- WordPress’s PHP code can be altered extensively in numerous places: in parent themes, child themes, and plugins.
- WordPress’s PHP code contains a great deal of global state: invisible statuses, such as the identity of the current post, that can affect your own code in ways that are difficult to predict.
- PHP code always fully executes before it’s viewable in-browser as HTML.
This third point means that, by default, you can’t look directly at PHP processing, only at its effects. This is different from, say, JavaScript, whose console.log
functionality allows you to “think with” JavaScript as it executes in your browser.
It’s also different from plain HTML and CSS, where what shows up in your browser is the markup (the “code”) itself, and can be transparently accessed and analyzed with tools like Chrome’s Developer Tools.
So today, I’m going to introduce the closest thing in PHP to console.log
: the print_r()
function. I’ll explain print_r()
and under what circumstances you can use it (not on live sites, please!), then present a couple of practical use cases in WordPress development.
What print_r()
Is and Why It’s Helpful
print_r()
prints information about a variable into HTML, so you can learn about that variable in your web browser.
According to PHP’s official function reference, print_r()
“prints human-readable information about a variable.” What that means is that it prints the values that a variable takes into HTML, so you can learn all about that variable directly in your web browser.
Here’s an example, straight from php.net:
$a = array( 'a' => 'apple', 'b' => 'banana', 'c' => array( 'x', 'y', 'z' ) );
print_r( $a );
If you run this code, the print_r()
command will print into your browser the following:
Array
(
[a] => apple
[b] => banana
[c] => Array
(
[0] => x
[1] => y
[2] => z
)
)
If you run the code above right before the post’s content—by hooking into the_content
, as we’ll discuss below—you see the following (in-browser on the left, in Chrome’s Developer Tools on the right):
Why is this cool? Because it lets you introspect into—understand everything about—the variables you’re working with as you do PHP development.
In other words, when you call, say, global $post;
to work with the current $post
object, you don’t just have to hope you understand what $post
has in it: you can actually check. You’ll start to see the power of this in the examples below.
Not for Live Sites
As
print_r()
spits ugly markup onto the page, running it on live sites is not advised.
print_r()
is for debugging, and the best place to debug things is in a staging environment. As print_r()
spits ugly markup onto the page, running it on live sites is not advised—although possible if you don’t have alternatives.
If you do need to run a var_dump()
on a live site, you can do it slightly more responsibly by enclosing the results in a hidden div
:
<div style="display: none;"><?php var_dump( $testvar ); ?></div>
You can then view the page source (using your browser’s “View Page Source” feature or its development tools feature set) to see the results of the var_dump()
without impacting live users.
print_r()
, var_dump()
, and echo
I don’t use print_r()
exclusively to inspect variables: two other methods, var_dump()
and echo
, can work similarly.
echo
, the main PHP function that prints things out to the page, can be used to inspect variables. However, it only works on strings and things that can be easily cast to strings, like integers. If you try to echo
an array, you get just Array
, and if you echo
an object, you crash the site with a fatal error—neither very helpful for our “figure out what’s going on” purposes.
I do use var_dump()
fairly often. var_dump()
is more thorough than print_r()
, but this means that it’s less readable, as in the following comparison:

print_r of a WP_Query
object

var-dump of the same WP_Query
object
However, sometimes you need var_dump()
to fill in information that print_r()
won’t show you, as in this example from Stack Overflow:
// Given $testarr = array( '', false, 42, array( '42' ) );
// Running var_dump( $testarr ); gives this result:
array(4) {
[0]=> string(0) ""
[1]=> bool(false)
[2]=> int(42)
[3]=> array(1) {[0]=>string(2) "42")}
}
// Running print_r( $testarr ); gives this result:
Array (
[0] =>
[1] =>
[2] => 42
[3] => Array ([0] => 42)
)
As you can see, print_r()
won’t distinguish between integers (42
) and numerical strings ("42"
), or between empty strings (""
) and the boolean false
. These distinctions matter, so reach for var_dump()
when you need it!
For our purposes, though, print_r()
is easier to read quickly, and it’s usually good enough to learn what we need to know about the variables we’re working with.
Example 1: Displaying All of a Post’s Custom Fields and their Values
For our first print_r()
demo, we’re going to inspect all of a post’s custom fields, also called its post meta. I had to do this exact inspection recently because I wasn’t sure what custom fields some of my post types were carrying.
In a staging (not live) environment, in a new plugin or in your theme’s functions.php
, the code we’ll write looks like this:
add_filter( 'the_content', 'wpshout_print_r_demo' );
function wpshout_print_r_demo( $content ) {
$meta = get_post_meta( get_the_ID() );
print_r( $meta );
return $content;
}
The code works as follows:
- We first hook into the
the_content
WordPress filter. We’re going to run our custom functionwpshout_print_r_demo()
, and we’re given the current post’s content,$content
, to play with. get_post_meta()
retrieves all custom fields for a given post ID, which we supply for the current post usingget_the_ID()
. We save all the fetched metadata to a variable,$meta
.- Next, we
print_r()
$meta
, putting it onto the page in a human-readable form. - Finally, we return the post’s content,
$content
, unchanged.
Why are we hooking this onto the the_content
filter? For two reasons: first, hooking into the_content
lets us use in-the-Loop functions like get_the_ID()
. Second, it lets us know exactly where our print_r
is going to print out: right above the content itself.
Here’s the result, viewed in-browser on the left and in Chrome Developer Tools on the right:
As you can see, we get an at-a-glance look at all the post meta attached to the current post—and as we browse the site, we’ll see this information for each post we look at until we disable the code above.
Example 2: Displaying the Posts Fetched by a Custom WP_Query
In this second print_r()
demo, we’re going to display the posts fetched by a custom WP_Query
. I run code similar to this frequently to quickly verify that my custom WP_Query
s are behaving as I expect.
Here’s the code:
add_filter( 'the_content', 'wpshout_print_r_demo' );
function wpshout_print_r_demo( $content ) {
$args = array(
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'ideas',
),
),
'orderby' => 'title',
'order' => 'DESC',
);
$newquery = new WP_Query( $args );
print_r( $newquery->posts );
return $content;
}
As before, we’re hooking into the_content
for convenience.
This time, we’re writing a custom query that fetches the following posts:
- Posts whose
post_type
ispost
, - In the “Ideas” category (whose slug is
ideas
), - Ordered in reverse alphabetical order.
We do this by creating an $args
variable that specifies the three parameters just listed. We then pass $args
into our WP_Query
constructor, and the resulting WP_Query
object gets saved to the variable $newquery
. (If you’re not familiar with writing custom queries in WordPress, please check out our guide on the subject.)
Now for our print_r()
: we’re going to print $newquery->posts
. This means that we want just the posts
property of the fetched WP_Query
object—not the whole object itself.
So what we get on the page is a list of fetched post objects, with all their properties:
As you can see, there’s a ton of data here; but scanning and seeing that each of the fetched posts is indeed from our “Ideas” category, and searching the page for post_title
(and seeing that it does indeed work in reverse alphabetical order), provides enough of a commonsense check that I’ve written my query properly.
Thanks for Reading!
This has been an introduction to a very important element of my day-to-day WordPress development: print_r()
and the power to actually understand what’s in a given variable. Thanks for reading, and we’d love to hear your comments and questions below!
Image credit: Ian Muttoo