Initiating WP_Query() with no args and adding them later through the query() method

Does calling the $query->query($args) method do anything different?

$query = new WP_Query( $args ); is simply a shortcut to the “instantiate class first, query later” version like $query = new WP_Query; $posts = $query->query( $args );. You can see it from the class constructor source here:

public function __construct( $query = '' ) {
    if ( ! empty( $query ) ) {
        $this->query( $query );
    }
}

Is it identical from a performance perspective? (I want to make sure
it’s not hitting the database twice.)

Yes, unless of course you do something like this:

$args = [ 'paged' => 2 ];
$query = new WP_Query( $args );
$posts = $query->query( $args );

Then that means double queries.

However, there’s a difference in the return value:

$query = new WP_Query( $args );  // returns an object
$posts = $query->query( $args ); // returns an array

And get_posts() (source) for example, uses the second approach.

I’m trying to understand if there’s a good reason why they did this

I don’t know why did they do it that way, but it is perfectly fine (although the code would be a few bytes more compact when using direct query upon instantiating the class). And I’d concern more on using the proper query parameters; e.g. using the proper post type, and setting no_found_rows to true when you don’t need pagination — in fact, setting it to true can improve performance.

Leave a Comment