WP::handle_404()
- Since
- 2.0.0
- Source
wp-includes/class-wp.php:724
Set the Headers for 404, if nothing is found for requested URL.
Description
Issue a 404 if a request doesn't match any posts and doesn't match any object (e.g. an existing-but-empty category, tag, author) and a 404 was not already issued, and if the request was not a search or the homepage. Otherwise, issue a 200. This sets headers after posts have been queried. handle_404() really means "handle status".By inspecting the result of querying posts, seemingly successful requests can be switched to a 404 so that canonical redirection logic can kick in.
Hooks fired · 1
One hook fires while WP::handle_404() runs, in this order:
- apply_filters( pre_handle_404 )filterline 738 (+14 into the body)
Filters whether to short-circuit default header status handling.
Uses · 21
- apply_filters()Calls the callback functions that have been added to a filter hook.
- is_404()Determines whether the query has resulted in a 404 (returns no results).
- is_admin()Determines whether the current request is for an administrative interface page.
- is_robots()Is the query for the robots.txt file?
- is_favicon()Is the query for the favicon.ico file?
- is_singular()Determines whether the query is for an existing single post of any post type (post, attachment, page, custom post types).
- str_contains()Polyfill for `str_contains()` function added in PHP 8.0.
- is_paged()Determines whether the query is for a paged result and not for the first page.
- get_query_var()Retrieves the value of a query variable in the WP_Query class.
- is_author()Determines whether the query is for an existing author archive page.
- is_user_member_of_blog()Finds out whether a user is a member of a given blog.
- is_tag()Determines whether the query is for an existing tag archive page.
Show all 21
- is_category()Determines whether the query is for an existing category archive page.
- is_tax()Determines whether the query is for an existing custom taxonomy archive page.
- is_post_type_archive()Determines whether the query is for an existing post type archive page.
- get_queried_object()Retrieves the currently queried object.
- is_home()Determines whether the query is for the blog homepage.
- is_search()Determines whether the query is for a search.
- is_feed()Determines whether the query is for a feed.
- status_header()Sets HTTP status header.
- nocache_headers()Sets the HTTP headers to prevent caching for the different browsers.
Used by · 1
- WP::main()Sets up all of the variables required by the WordPress environment.
Source
public function handle_404() { global $wp_query; /** * Filters whether to short-circuit default header status handling. * * Returning a non-false value from the filter will short-circuit the handling * and return early. * * @since 4.5.0 * * @param bool $preempt Whether to short-circuit default header status handling. Default false. * @param WP_Query $wp_query WordPress Query object. */ if ( false !== apply_filters( 'pre_handle_404', false, $wp_query ) ) { return; } // If we've already issued a 404, bail. if ( is_404() ) { return; } $set_404 = true; // Never 404 for the admin, robots, or favicon. if ( is_admin() || is_robots() || is_favicon() ) { $set_404 = false; // If posts were found, check for paged content. } elseif ( $wp_query->posts ) { $content_found = true; if ( is_singular() ) { $post = isset( $wp_query->post ) ? $wp_query->post : null; $next = '<!--nextpage-->'; // Check for paged content that exceeds the max number of pages. if ( $post && ! empty( $this->query_vars['page'] ) ) { // Check if content is actually intended to be paged. if ( str_contains( $post->post_content, $next ) ) { $page = trim( $this->query_vars['page'], '/' ); $content_found = (int) $page <= ( substr_count( $post->post_content, $next ) + 1 ); } else { $content_found = false; } } } // The posts page does not support the <!--nextpage--> pagination. if ( $wp_query->is_posts_page && ! empty( $this->query_vars['page'] ) ) { $content_found = false; } if ( $content_found ) { $set_404 = false; } // We will 404 for paged queries, as no posts were found. } elseif ( ! is_paged() ) { $author = get_query_var( 'author' ); // Don't 404 for authors without posts as long as they matched an author on this site. if ( is_author() && is_numeric( $author ) && $author > 0 && is_user_member_of_blog( $author ) // Don't 404 for these queries if they matched an object. || ( is_tag() || is_category() || is_tax() || is_post_type_archive() ) && get_queried_object() // Don't 404 for these queries either. || is_home() || is_search() || is_feed() ) { $set_404 = false; } } if ( $set_404 ) { // Guess it's time to 404. $wp_query->set_404(); status_header( 404 ); nocache_headers(); } else { status_header( 200 );History
Introduced in 2.0.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.9.7 tag, from
src/wp-includes/class-wp.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.