get_terms( array|string $args = array(), array|string $deprecated = '' ): WP_Term[]|int[]|string[]|string|WP_Error
- Since
- 2.3.0, 4.2.0, 4.4.0, 4.5.0, 4.8.0
- Source
wp-includes/taxonomy.php:1316
Queries one or more taxonomies for matching term objects by passing an $args array whose 'taxonomy' key names the taxonomy or taxonomies to search. It wraps WP_Term_Query::query(), accepts the same arguments (hide_empty, orderby, include, and more), and returns a WP_Error if any requested taxonomy is not registered. A legacy two-parameter calling style ($taxonomy, $args) is still supported for old code, which is detected automatically based on the shape of the first argument.
Description
You can fully inject any customizations to the query before it is sent, as well as control the output with a filter.
The return type varies depending on the value passed to $args['fields']. See WP_Term_Query::get_terms() for details. In all cases, a WP_Error object will be returned if an invalid taxonomy is requested.
The 'get_terms' filter will be called when the cache has the term and will pass the found term along with the array of $taxonomies and array of $args.
This filter is also called before the array of terms is passed and will pass the array of terms, along with the $taxonomies and $args.
The 'list_terms_exclusions' filter passes the compiled exclusions along with the $args.
The 'get_terms_orderby' filter passes the ORDER BY clause for the query along with the $args array.
Taxonomy or an array of taxonomies should be passed via the 'taxonomy' argument in the $args array:
$terms = get_terms( array(
'taxonomy' => 'post_tag',
'hide_empty' => false,
) ); Prior to 4.5.0, taxonomy was passed as the first parameter of get_terms().
Compatibility
- WordPress
- since 4.8.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
$argsarray|stringoptional- Array or string of arguments. See WP_Term_Query::__construct() for information on accepted arguments. Default empty array.Default:
array() $deprecatedarray|stringoptional- Argument array, when using the legacy function parameter format.
If present, this parameter will be interpreted as$args, and the first function parameter will be parsed as a taxonomy or array of taxonomies.
Default empty.Default:''
Return value
WP_Term[]|int[]|string[]|string|WP_Error- Array of terms, a count thereof as a numeric string, or WP_Error if any of the taxonomies do not exist.
See the function description for more information.
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.
List all category and tag terms with their post counts
Pull every category and tag registered on the site, including empty ones, and print their names and counts.
$terms = get_terms(
array(
'taxonomy' => array( 'category', 'post_tag' ),
'hide_empty' => false,
)
);
if ( is_wp_error( $terms ) ) {
echo esc_html( $terms->get_error_message() );
} else {
foreach ( $terms as $term ) {
echo esc_html( $term->taxonomy . ': ' . $term->name . ' (' . $term->count . ')' ) . '<br>';
}
}Fetch category terms using the old two-argument signature
Migrate a pre-4.5.0 call that passed the taxonomy name first and the query args second.
$categories = get_terms(
'category',
array(
'hide_empty' => false,
'orderby' => 'name',
)
);
if ( is_wp_error( $categories ) ) {
echo esc_html( $categories->get_error_message() );
} else {
foreach ( $categories as $category ) {
echo esc_html( $category->name ) . '<br>';
}
}This legacy form still works because a non-empty second parameter forces get_terms() onto the old calling convention.
Common problems and fixes · 4
- Why does get_terms() come back empty even though I created the terms?
- Why did get_terms() return a WP_Error instead of a list of terms?
- Why doesn't my 'get_terms' filter callback ever run?
- Why did an array I passed as the first argument get treated as a list of taxonomies instead of as $args?
Why does get_terms() come back empty even though I created the terms?
'hide_empty' => false in $args
- Or attach the term to a post first with wp_set_object_terms()Why did get_terms() return a WP_Error instead of a list of terms?
is_wp_error( $terms ) before looping
- Confirm the custom taxonomy's register_taxonomy() call runs on every page load, not just onceWhy doesn't my 'get_terms' filter callback ever run?
$args['suppress_filter'] to true returns the raw terms before the filter fires, and the source explicitly skips the filter when the query returns a plain count instead of an array ('Count queries are not filtered, for legacy reasons'). Check whether you passed 'fields' => 'count' or 'suppress_filter' => true.Why did an array I passed as the first argument get treated as a list of taxonomies instead of as $args?
Alternatives and related functions
get_term- When you already know a single term's ID and just need that one term object instead of running a query.
wp_get_post_terms- When you need the terms assigned to one specific post rather than every term in a taxonomy.
get_categories- When you specifically want category terms and prefer a shorthand wrapper instead of setting 'taxonomy' yourself.
WP_Term_Query- When you want direct access to the query object, for example to inspect query_vars or reuse the same query multiple times.
Performance profile
How much work a call to get_terms() 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
- Heavy
- Scaling
- Scales with input
- Instructions
- 38–63
- Plugin surface
- 1 hook
- Called by
- 33
Reaches the database via ->query().
The body loops, so the work grows with what you pass in.
Executed per call on PHP 8.5, depending on the branch taken. The body compiles to 87.
Third-party callbacks on 'get_terms' run inside this call, and their cost is not bounded by anything here.
33 places in core call this, so the cost is paid more often than your own code shows.
What it touches
- querycontent query
get_terms()this function does it - hookthird-party callbacks
apply_filters()called directly - sqldatabase query
->query()called directly
Further down the call graph this can also reach option, cache, serialize and transient. Those are the worst case, several calls deep and usually down an error path, not what a normal call pays.
What one call costs · 3 distinct outcomes
One number would be a lie: the work depends on which branch runs. These are every distinct cost get_terms() can have, taken from its control-flow graph on PHP 8.5.
| When | Instructions | Calls it makes |
|---|---|---|
| always | 38–51 | wp_parse_args(), array_intersect_key(), wp_parse_args(), ->query() |
!empty($args) && !$args && !taxonomy_exists() | 45–53 | wp_parse_args(), array_intersect_key(), wp_parse_args(), taxonomy_exists(), __() |
is_array($terms) && !$args | 51–63 | wp_parse_args(), array_intersect_key(), wp_parse_args(), ->query(), apply_filters() |
Across PHP versions
| PHP | Compiled | Executed | Branches | Notes |
|---|---|---|---|---|
| 8.6-dev | 87 | 38–63 | 10 | |
| 8.5 | 87 | 38–63 | 10 | |
| 8.4 | 87 | 38–63 | 10 | |
| 8.3 | 87 | 38–63 | 10 | |
| 8.2 | 87 | 38–63 | 10 | |
| 8.1 | 87 | 38–63 | 10 | 1 fewer instruction than PHP 7.4 |
| 7.4 | 88 | 38–64 | 10 |
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.
Hooks and filters fired · 1
One hook fires while get_terms() runs, in this order:
Uses · 6
- wp_parse_args()Merges user defined arguments into defaults array.
- taxonomy_exists()Determines whether the taxonomy name exists.
- __()Retrieves the translation of $text.
- apply_filters()Calls the callback functions that have been added to a filter hook.
- WP_Term_Query::__construct()Constructor.
- WP_Error::__construct()Initializes the error.
Used by · 33
- WP_Customize_Nav_Menus::load_available_items_query()Performs the post_type and taxonomy queries for loading available menu items.
- WP_Customize_Nav_Menus::search_available_items_query()Performs post queries for available-item searching.
- WP_Posts_List_Table::formats_dropdown()Displays a formats drop-down for filtering items.
- WP_REST_Terms_Controller::get_items()Retrieves terms associated with a taxonomy.
- WP_Term_Query::get_terms()Retrieves the query results.
- WP_Terms_List_Table::prepare_items()
- WP_Widget_Links::form()Outputs the settings form for the Links widget.
- Walker_Category::start_el()Starts the element output.
- _get_term_hierarchy()Retrieves children of taxonomy as term IDs.
- _wp_ajax_menu_quick_search()Prints the appropriate response to a menu quick search.
- export_wp()Generates the WXR export file for download.
- get_all_category_ids()Retrieves all category IDs.
Show all 33
- get_categories()Retrieves a list of category objects.
- get_category_by_path()Retrieves a category based on URL containing the category slug.
- get_tags()Retrieves all post tags.
- get_term_by()Gets all term data from database by term field and data.
- taxonomy_meta_box_sanitize_cb_input()Sanitizes POST values from an input taxonomy metabox.
- term_exists()Determines whether a taxonomy term exists.
- wp_ajax_ajax_tag_search()Handles tag search via AJAX.
- wp_ajax_get_tagcloud()Handles getting a tagcloud via AJAX.
- wp_count_terms()Counts how many terms are in taxonomy.
- wp_dropdown_categories()Displays or retrieves the HTML dropdown list of categories.
- wp_get_nav_menus()Returns all navigation menu objects.
- wp_get_object_terms()Retrieves the terms associated with the given object(s), in the supplied taxonomies.
- wp_insert_term()Adds a new term to the database.
- wp_link_category_checklist()Outputs a link category checklist element.
- wp_list_bookmarks()Retrieves or echoes all of the bookmarks.
- wp_nav_menu_item_taxonomy_meta_box()Displays a meta box for a taxonomy menu item.
- wp_popular_terms_checklist()Retrieves a list of the most popular terms from the specified taxonomy.
- wp_tag_cloud()Displays a tag cloud.
- wp_terms_checklist()Outputs an unordered list of checkbox input elements labelled with term names.
- wp_xmlrpc_server::_insert_post()Helper method for wp_newPost() and wp_editPost(), containing shared logic.
- wp_xmlrpc_server::wp_getTerms()Retrieves all terms for a taxonomy.
Source code
function get_terms( $args = array(), $deprecated = '' ) { $term_query = new WP_Term_Query(); $defaults = array( 'suppress_filter' => false, ); /* * Legacy argument format ($taxonomy, $args) takes precedence. * * We detect legacy argument format by checking if * (a) a second non-empty parameter is passed, or * (b) the first parameter shares no keys with the default array (ie, it's a list of taxonomies) */ $_args = wp_parse_args( $args ); $key_intersect = array_intersect_key( $term_query->query_var_defaults, (array) $_args ); $do_legacy_args = $deprecated || empty( $key_intersect ); if ( $do_legacy_args ) { $taxonomies = (array) $args; $args = wp_parse_args( $deprecated, $defaults ); $args['taxonomy'] = $taxonomies; } else { $args = wp_parse_args( $args, $defaults ); if ( isset( $args['taxonomy'] ) && null !== $args['taxonomy'] ) { $args['taxonomy'] = (array) $args['taxonomy']; } } if ( ! empty( $args['taxonomy'] ) ) { foreach ( $args['taxonomy'] as $taxonomy ) { if ( ! taxonomy_exists( $taxonomy ) ) { return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) ); } } } // Don't pass suppress_filter to WP_Term_Query. $suppress_filter = $args['suppress_filter']; unset( $args['suppress_filter'] ); $terms = $term_query->query( $args ); // Count queries are not filtered, for legacy reasons. if ( ! is_array( $terms ) ) { return $terms; } if ( $suppress_filter ) { return $terms; } /** * Filters the found terms. * * @since 2.3.0 * @since 4.6.0 Added the `$term_query` parameter. * * @param array $terms Array of found terms. * @param array|null $taxonomies An array of taxonomies if known. * @param array $args An array of get_terms() arguments. * @param WP_Term_Query $term_query The WP_Term_Query object. */ return apply_filters( 'get_terms', $terms, $term_query->query_vars['taxonomy'], $term_query->query_vars, $term_query );}Changelog
Introduced in 4.8.0. Unchanged from 6.7.7 through 7.1.0.
Signature, return type and hooks compared across 5 parsed releases.
$args array can be provided as the first parameter.Introduced 'meta_key' and 'meta_value' parameters. Introduced the ability to order results by metadata.from the docblock
orderby parameter.Introduced the 'meta_query' and 'update_term_meta_cache' parameters. Converted to return a list of WP_Term objects.from the docblock
About this page
- Parsed data
- Generated from the wordpress-develop 6.8.8 tag, from
src/wp-includes/taxonomy.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.