wp-includes/post.php:1092Resolve a post ID, a post object, or the current global $post into a single WP_Post, an associative array, or a numeric array. The $post argument is falsey-tolerant: 0, null and false all fall back to the global post, which is why calls outside the loop return null rather than an error. Fields come back raw by default, so anything destined for a page still needs its display filters applied.
Retrieves post data given a post ID or post object.
$postint|WP_Post|nulloptionalnull$outputstringoptionalOBJECT$filterstringoptional'raw'WP_Post|array|nullEvery 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.
Passing ARRAY_A is the quickest way to read post fields without touching WP_Post property syntax.
$post = get_post( 2, ARRAY_A );
if ( $post ) {
echo esc_html( $post['post_title'] ), "\n";
echo esc_html( $post['post_status'] ), "\n";
} else {
echo 'No post with that ID.';
}ARRAY_N returns the same fields keyed numerically, which is rarely what you want.
With no arguments the function falls back to the global $post, so template parts can stay self-contained.
// Stand in for the loop by setting the global the way a template would.
$GLOBALS['post'] = get_post( 3 );
$post = get_post();
echo $post ? esc_html( $post->post_title ) : 'No global post is set.';Outside the loop there is no global $post, so guard the return value.
get_post() returns raw database values, so content read this way is not what the front end shows.
$post = get_post( 1 );
if ( $post ) {
echo "RAW:\n", esc_html( $post->post_content ), "\n\n";
echo "FILTERED:\n", esc_html( apply_filters( 'the_content', $post->post_content ) );
}Applying 'the_content' also runs shortcodes, oEmbed and block rendering.
Two different paths end in null. A falsey $post (0, null, false, '') makes the function fall back to $GLOBALS['post'], so calling it outside the loop, in an admin screen, or in a REST or cron request returns null because no global post is set. A numeric ID that has no matching row also returns null, because WP_Post::get_instance() fails and the function returns early. Always test the return value before reading a property from it.
$filter defaults to 'raw', which returns the values exactly as stored. Paragraph tags, shortcodes, blocks and embeds are all applied by the the_content filter at render time, not by this function. Run apply_filters( 'the_content', $post->post_content ) when you need the rendered output, and remember that doing so executes shortcodes.
They select the return shape only, never which fields are loaded. OBJECT (the default) returns a WP_Post instance with magic properties and lazy loading for fields like post_category. ARRAY_A returns the same fields as a string-keyed array and ARRAY_N as a numerically indexed one. Only the OBJECT form gives you WP_Post behavior, so array callers lose the lazy properties.
No. Numeric IDs go through WP_Post::get_instance(), which reads from the posts object cache group and only queries when the post is not cached. Calling it several times in one request for the same ID is cheap. Passing a plain stdClass object is the expensive path, because it is sanitized and wrapped on every call.
get_postsWP_Queryget_post_fieldget_page_by_pathfunction get_post( $post = null, $output = OBJECT, $filter = 'raw' ) { if ( empty( $post ) && isset( $GLOBALS['post'] ) ) { $post = $GLOBALS['post']; } if ( $post instanceof WP_Post ) { $_post = $post; } elseif ( is_object( $post ) ) { if ( empty( $post->filter ) ) { $_post = sanitize_post( $post, 'raw' ); $_post = new WP_Post( $_post ); } elseif ( 'raw' === $post->filter ) { $_post = new WP_Post( $post ); } else { $_post = WP_Post::get_instance( $post->ID ); } } else { $_post = WP_Post::get_instance( $post ); } if ( ! $_post ) { return null; } $_post = $_post->filter( $filter ); if ( ARRAY_A === $output ) { return $_post->to_array(); } elseif ( ARRAY_N === $output ) { return array_values( $_post->to_array() ); } return $_post;}Introduced in 1.5.1. One change between 6.7.7 and 7.1.0.
Signature, return type and hooks compared across 5 parsed releases.
$post retyped from int|WP_Post|null to int|object|null.verified against sourcesrc/wp-includes/post.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it.