Skip to content

WP_Query::get_posts use case clarification #2210

@ahollister

Description

@ahollister

Issue Description

I've encountered a pretty gnarly issue a few times with my (incorrect) usage of WP_Query::get_posts() which can be quite tricky to debug.

Essentially, new WP_Query($args)->get_posts() can silently corrupt tax_query results due to core code that writes the first taxonomy and term to query_vars['taxonomy'] and query_vars['term'] which then effects the SQL generated when WP_Query::get_posts() runs the query for the second time.

This causes incorrect results particularly when you're trying to do a tax_query with multiple taxonomies and term arrays with 'relation' => 'AND' and 'operator' => 'IN' - (for example, if you're using wp_query to build faceted search interfaces). The first taxonomy and term end up appended as a new separate clause with a single term, even if that taxonomy had multiple terms in the originally passed arguments.

I don't really think this is a bug, its more an issue of me not realising that WP_Query::get_posts() should only ever be used internally and should never be used to get results from the already constructed WP_Query object.

The documentation page for WP_Query::get_posts() is usually going to be the first result if you google something like "get posts from a wp_query", the method name can be easily misconstrued as a simple getter, and the documentation is minimal.

URL of the Page with the Issue

https://developer.wordpress.org/reference/classes/wp_query/get_posts/

Section of Page with the issue

Description

Why is this a problem?

Its perfectly reasonable for a developer to end up on this documentation page when looking up how to get the results from an already constructed WP_Query and incorrectly assume that this method is what they want. In lots of cases, this would lead to that developer using ->get_posts() instead of ->posts. This will often be missed, since get_posts will re-run the query and often produce the same results, however it is inefficient because they would essentially be running the query twice, and it can produce unexpected silent failures in complex tax_queries as described above in the Issue Description.

Suggested Fix

I think the fix is a one line documentation change:

"Note: This method is used internally by WP_Query and should not be used to retrieve post results from an already instantiated WP_Query object. To get the array of post results from a WP_Query, you should use ->posts instead"

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions