Sometimes you need to throw a 404 if certain conditions are met and doing so in WordPress requires a little trickery to achieve the full effect.
I don’t want to go into a discussion about whether this would ever be correct behaviour but I will say this: if a URL is sometimes not found, that means it is sometimes found and if so, a different HTTP Status Code in the 4xx category would probably be more applicable, e.g. 401 if your condition is whether the user is logged in, or 405 if there’s a GET
where only a POST
is allowed. In this case, wp_die()
would be a more sensible decision.
That said, there are odd occasions when this will be useful and I leave it to you to make such a judgement.
How it works
Throwing a 404 in WordPress requires 5 main steps:
- Make
is_*
functions return correct values: e.g.is_404()
should returntrue
andis_archive()
should returnfalse
- Ensure HTML title is correct: Depending on the request and your theme, the
<title>
might not always change - Throw HTTP Status Code 404: A 404 page needs to return 404, or it’ll be what’s called a “Soft 404”, which are misleading
- Show the 404 template: The user needs to be shown the 404 page (because this isn’t all about machines!)
- Stop execution: WordPress will want to continue with the request so
exit;
ensures nothing shows after the 404 template
The Code
function fourohfour() { // 1. Ensure `is_*` functions work global $wp_query; $wp_query->set_404(); // 2. Fix HTML title add_action( 'wp_title', function () { return '404: Not Found'; }, 9999 ); // 3. Throw 404 status_header( 404 ); nocache_headers(); // 4. Show 404 template require get_404_template(); // 5. Stop execution exit; }
Conclusion
As aforementioned, it’s very unlikely this would ever be desirable behaviour, but never say never!
pls explain me how to add this hook in functions.php
To use this in your `functions.php` just paste the function in there and then call it with `fourohfour()`.
For example, if you want to really infuriate your users you could do something like `if (time() % 2) { fourohfour(); }` :P