WP_Query::__construct( string|array $query = '' )
- Since
- 1.5.0
- Source
wp-includes/class-wp-query.php:3982
Builds a WP_Query object and immediately runs the query only when the $query argument is not empty, accepting either a URL-style query string or an array of query vars. Passing nothing (the default) skips the query entirely, leaving the object with no posts until you call WP_Query::query() yourself. Most theme and plugin code calls this indirectly through `new WP_Query( $args )` rather than referencing the constructor by name.
Description
Sets up the WordPress query, if parameter is not empty.
Compatibility
- WordPress
- since 1.5.0
- PHP
- 7.4–8.6-dev
- 6.7.7
- 6.8.8
- 6.9.7
- 7.0.4
- 7.1.0
Present in every tracked release (6.7.7 to 7.1.0), and compiles on PHP 7.4 through 8.6-dev.
Parameters
$querystring|arrayoptional- URL query string or array of vars.Default:
''
Code examples
Every example is editable and runs in a real WordPress booted in your browser by WordPress Playground. Press Run, then edit the code: clicking away re-runs it. Nothing is sent anywhere until you do.
Run a custom loop over posts in a category
Instantiate WP_Query with an array of args to pull posts from the news category outside the main loop.
$news_query = new WP_Query( array(
'category_name' => 'news',
'posts_per_page' => 5,
) );
if ( $news_query->have_posts() ) {
while ( $news_query->have_posts() ) {
$news_query->the_post();
echo esc_html( get_the_title() ) . '<br>';
}
wp_reset_postdata();
} else {
echo 'No posts found in the news category.';
}wp_reset_postdata() restores the global $post after the custom loop finishes.
Query posts that have a specific meta key
Pass a meta_key argument to the constructor to find posts carrying the price meta field.
$priced_query = new WP_Query( array(
'meta_key' => 'price',
'meta_compare' => 'EXISTS',
'posts_per_page' => -1,
) );
echo esc_html( sprintf( 'Found %d post(s) with a price meta key.', $priced_query->post_count ) );
wp_reset_postdata();Common problems and fixes · 3
- Why does new WP_Query() with no arguments return zero posts?
- Why does my sidebar loop reset the main loop's posts?
- Can I pass a URL-style query string instead of an array?
Why does new WP_Query() with no arguments return zero posts?
Why does my sidebar loop reset the main loop's posts?
Can I pass a URL-style query string instead of an array?
Alternatives and related functions
get_posts- When you just need a plain array of post objects and don't need to loop with the_post() or manage pagination manually.
WP_Query::query- When you already have a WP_Query instance and want to re-run it with a new set of arguments instead of creating a second object.
pre_get_posts- When you want to modify WordPress's existing main query instead of instantiating a separate WP_Query object.
WP_User_Query- When the data you need to query is users rather than posts.
Performance profile
How much work a call to WP_Query::__construct() does, and what it touches: the algorithmic scaling, the Zend instruction count per call across PHP versions, the hooks it hands control to, and the core code that calls it. Measured from the compiled opcodes, not a stopwatch, so every number is identical on any machine running the same PHP version, and every function in core is ranked by cost.
- Cost class
- Trivial
- Scaling
- Constant
- Instructions
- 4–7
- Plugin surface
- None
- Called by
- 45
Reaches the database via ->query().
No loop in the body: the same number of instructions runs whatever you pass in.
Executed per call on PHP 8.5, depending on the branch taken. The body compiles to 7.
Nothing here hands control to plugin code.
45 places in core call this, so the cost is paid more often than your own code shows.
What it touches
- sqldatabase query
->query()called directly
What one call costs · 2 distinct outcomes
One number would be a lie: the work depends on which branch runs. These are every distinct cost WP_Query::__construct() can have, taken from its control-flow graph on PHP 8.5.
| When | Instructions | Calls it makes |
|---|---|---|
empty($query) | 4 | none |
!empty($query) | 7 | ->query() |
Across PHP versions
Compiles the same on PHP 7.4, 8.1, 8.2, 8.3, 8.4, 8.5 and 8.6-dev: 7 instructions, 4–7 executed per call, 1 branch. The work does not change between versions.
An instruction is not a fixed amount of time, so a matching count is not necessarily the same speed; what it rules out is a difference in the work itself.
Uses · 1
- WP_Query::query()Sets up the WordPress query by parsing query string.
Used by · 45
- Twenty_Eleven_Ephemera_Widget::widget()Outputs the HTML for this widget.
- Twenty_Fourteen_Ephemera_Widget::widget()Output the HTML for this widget.
- WP_Customize_Manager::find_changeset_post_id()Finds the changeset post ID for a given changeset UUID.
- WP_Customize_Manager::import_theme_starter_content()Imports theme starter content into the customized state.
- WP_Customize_Nav_Menus::search_available_items_query()Performs post queries for available-item searching.
- WP_Embed::find_oembed_post_id()Finds the oEmbed cache post ID for a given cache key.
- WP_Navigation_Fallback::get_most_recently_published_navigation()Finds the most recently published `wp_navigation` post type.
- WP_Privacy_Requests_Table::prepare_items()Prepares items to output.
- WP_REST_Font_Faces_Controller::create_item()Creates a font face for the parent font family.
- WP_REST_Font_Families_Controller::create_item()Creates a single font family.
- WP_REST_Font_Families_Controller::get_font_face_ids()Get the child font face post IDs.
- WP_REST_Global_Styles_Revisions_Controller::get_items()Returns paginated revisions of the given global styles config custom post type.
Show all 45
- WP_REST_Post_Search_Handler::search_items()Searches posts for a given search request.
- WP_REST_Posts_Controller::get_items()Retrieves a collection of posts.
- WP_REST_Revisions_Controller::get_items()Gets a collection of revisions.
- WP_Sitemaps_Posts::get_max_num_pages()Gets the max number of pages available for the object type.
- WP_Sitemaps_Posts::get_url_list()Gets a URL list for a post type sitemap.
- WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles()Returns the custom post type that contains the user's origin config for the active theme or an empty array if none are found.
- WP_Widget_Recent_Posts::widget()Outputs the content for the current Recent Posts widget instance.
- _WP_Editors::wp_link_query()Performs post queries for internal linking.
- _wp_ajax_menu_quick_search()Prints the appropriate response to a menu quick search.
- _wp_build_title_and_description_for_single_post_type_block_template()Builds the title and description of a post-specific template based on the underlying referenced post.
- _wp_personal_data_cleanup_requests()Cleans up failed and expired requests before displaying the list table.
- block_core_navigation_get_most_recently_published_navigation()Finds the most recently published `wp_navigation` Post.
- get_block_template()Retrieves a single unified template object using its id.
- get_block_templates()Retrieves a list of unified template objects based on a query.
- get_pages()Retrieves an array of pages (or hierarchical post type items).
- get_posts()Retrieves an array of the latest posts, or posts matching the given criteria.
- query_posts()Sets up The Loop with query parameters.
- render_block_core_latest_posts()Renders the `core/latest-posts` block on server.
- render_block_core_post_template()Renders the `core/post-template` block on the server.
- render_block_core_query_no_results()Renders the `core/query-no-results` block on the server.
- render_block_core_query_pagination_next()Renders the `core/query-pagination-next` block on the server.
- render_block_core_query_pagination_numbers()Renders the `core/query-pagination-numbers` block on the server.
- render_block_core_template_part()Renders the `core/template-part` block on the server.
- url_to_postid()Examines a URL and try to determine the post ID it represents.
- wp_ajax_query_attachments()Handles querying attachments via AJAX.
- wp_create_user_request()Creates and logs a user request to perform a specific action.
- wp_dashboard_recent_posts()Generates Publishing Soon and Recently Published sections.
- wp_filter_wp_template_unique_post_slug()Generates a unique slug for templates.
- wp_get_associated_nav_menu_items()Returns the menu items associated with a particular object.
- wp_get_custom_css_post()Fetches the `custom_css` post for a given theme.
- wp_get_latest_revision_id_and_total_count()Returns the latest revision ID and count of revisions for a post.
- wp_media_personal_data_exporter()Finds and exports attachments associated with an email address.
- wp_nav_menu_item_post_type_meta_box()Displays a meta box for a post type menu item.
Source code
public function __construct( $query = '' ) { if ( ! empty( $query ) ) { $this->query( $query ); } }Changelog
Introduced in 1.5.0. Unchanged from 6.7.7 through 7.1.0.
Signature, return type and hooks compared across 5 parsed releases.
About this page
- Parsed data
- Generated from the wordpress-develop 6.7.7 tag, from
src/wp-includes/class-wp-query.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it. - Corrections
- Something wrong on this page? Report it and it gets fixed in the next regeneration.