Opened 12 months ago
Last modified 10 days ago
#20904 new defect (bug)
WP_Query instances getting entangled with $wp_query global
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Future Release |
| Component: | Query | Version: | |
| Severity: | normal | Keywords: | has-patch 3.5-early |
| Cc: |
Description
WP_Query::the_post() fires setup_postdata(), which then uses get_query_var(). get_query_var(), in turn, calls the get() method on the $wp_query global object. In this way, WP_Query instances are not truly insulated from each other - they all are tied up with $wp_query in a way that seems unnecessary, and causes fatal errors in some cases.
In normal use, you would never really notice the issue, because after the 'init' action, the following offending line in setup_postdata() will return the 'page' query var from $wp_query:
$page = get_query_var('page');
And, since secondary WP_Query instances don't paginate in the same way as the primary query, the 'page' property on those instances doesn't matter much. So, while the value of $page is not strictly speaking correct in these cases (it comes from the wrong object), it generally fails silently.
However, if you instantiate a WP_Query object before 'init', you get a fatal error, because $wp_query->get() is an undefined method. Here's a simple mu-plugin that will demonstrate the problem:
function bbg_create_early_wp_query_object() {
$q = new WP_Query( array(
'post_type' => 'post'
) );
if ( $q->have_posts() ) {
while ( $q->have_posts() ) {
$q->the_post();
}
}
}
add_action( 'plugins_loaded', 'bbg_create_early_wp_query_object' );
My suggested solution is to move the setup_postdata() logic into a method of the WP_Query class, and then use $this->get( 'page' ) rather than get_query_var( 'page' ), to ensure that you're referring to the query vars of the correct query object. The old function setup_postdata() then becomes a wrapper for $wp_query->setup_postdata().
In addition, I modified the way that the $more global is set, so that it references the current object as well. This prevents _doing_it_wrong() errors when firing up a WP_Query instance before 'init'.
Attachments (1)
Change History (4)
boonebgorges — 12 months ago
- Keywords 3.5-early added
- Milestone changed from Awaiting Review to Future Release
comment:2
wonderboymusic — 5 months ago
- Milestone changed from Future Release to 3.6

We're still tied to all those globals, but this is definitely an improvement.