The code below returns 0 for pages on the frontend.

 * @uses WP_Query
 * @uses get_queried_object()
 * @see get_the_ID()
 * @return int
function get_the_post_id() {
  if (in_the_loop()) {
       $post_id = get_the_ID();
  } else {
       global $wp_query;
       $post_id = $wp_query->get_queried_object_id();
  return $post_id;

$page_id = get_the_post_id();
echo $page_id;
  • 1
    If you're just running get_the_post_id(); in functions.php outside the function then it's too early and the queried object hasn't been determined yet. Aug 19, 2022 at 6:06

1 Answer 1


Plugins and themes are loaded pretty early in WordPress's lifecycle. Assuming this code is a plugin file or a theme's functions.php file, then it is executing before WordPress has set up the query, or even parsed the arguments in the request. The queried object ID is 0 because no query has taken place yet :)

Try running the code in a hook after WordPress has finished executing the main query instead:

function wpse408763_test() {
  echo get_the_post_id();

add_action( 'wp', 'wpse408763_test' );

It's worth mentioning that WPDB::get_queried_object_id() can return values which do not correspond to a post at all - on a taxonomy term archive page, it will be the ID of the term, for example, which would result in the get_the_post_id() function returning a term ID when used outside the loop but the current post's ID within the loop. You might want to consider only returning the value from get_queried_object_id() in the case of is_single() || is_page() and perhaps false otherwise in order to mitigate some headaches down the road.

There's also a global wrapper such that you needn't manually reference the $wpdb global yourself.

  • thanks. It had me at my wits end. Would you recommend that $post_id = get_the_ID(); is sufficient and the rest of the code is superfluous?
    – Motivated
    Aug 19, 2022 at 6:19
  • It really depends on the use-case. get_the_ID() by itself is sufficient for retrieving the current post ID within The Loop, but if you need to know the ID of a single-post request anywhere else (i.e. template_redirect, header template file, for use in some secondary query, etc.) then you'll probably still need get_queried_object_id() in some form. IMO, I feel like the two use-cases are distinct enough that it probably usually doesn't make a lot of sense to try and cover them both with one general function, however
    – bosco
    Aug 19, 2022 at 6:30
  • Thanks. That's super helpful to know. Be keen to pick your brains more if that's okay - chat.stackexchange.com/rooms/138624/wordpress
    – Motivated
    Aug 19, 2022 at 6:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.