get_post_meta( int $post_id, string $key = , bool $single = false ): mixed

Retrieves a post meta field for the given post ID.


Post ID.
The meta key to retrieve. By default, returns data for all keys.


Whether to return a single value.
This parameter has no effect if $key is not specified.



mixed An array of values if $single is false.
The value of the meta field if $single is true.
False for an invalid $post_id (non-numeric, zero, or negative value).
An empty string if a valid but non-existing post ID is passed.

More Information

  • Please note that if a db collation is case insensitive (has with suffix _ci) then update_post_meta and delete_post_meta and get_posts() will update/delete/query the meta records with keys that are upper or lower case. However get_post_meta will apparently be case sensitive due to WordPress caching. See for more info. Be careful not to mix upper and lowercase.
  • Uses: get_metadata() to retrieve the metadata.


function get_post_meta( $post_id, $key = '', $single = false ) {
	return get_metadata( 'post', $post_id, $key, $single );



User Contributed Notes

  1. Skip to note 16 content

    Return values when no meta field is found
    If a meta field with the given $key isn’t found for the given $post_id, the return value varies:

    If $single is true, an empty string is returned.
    If $single is false, an empty array is returned.

    Since both evaluate as false, you can use get_post_meta directly in conditionals, like this:

    if( ! get_post_meta( '1', 'non-existing_meta', true ) ) {}
    if( ! get_post_meta( '1', 'non-existing_meta', false ) ) {}
    // both ifs will get run if no meta field is found; since
    // array() == false and '' == false

    What if I want to store an empty string?
    If for some reason your with to store an empty string or array into your meta field, get_post_meta will not be reliable when checking if the given meta field exists.
    In this case, you can use get_post_custom_keys to do so:

    if( ! in_array( 'given_key', get_post_custom_keys( '1' ) ) ) {} 
    // this correctly checks for the existence of the given key, 
    // even if it's empty or has a value that evaluates as false. 
  2. Skip to note 17 content

    The best thing about this function is that you no longer need to use it :)

    Since r21559 (v3.5), you can just call $post->foo to fetch the equivalent of get_post_meta( $post->ID, 'foo', true ).

    You can even extend that to introduce dynamically-generated fields, so you can call echo esc_html( $post->bar ) instead of $bar = some_custom_logic( get_post_meta( $post->ID, 'bar', true ) ); echo esc_html( $bar ).

    This makes code a lot cleaner and more readable.

    add_filter( 'get_post_metadata', 'add_dynamic_post_meta', 10, 4 );
     * Add dynamically-generated "post meta" to `\WP_Post` objects
     * This makes it possible to access dynamic data related to a post object by simply referencing `$post->foo`.
     * That keeps the calling code much cleaner than if it were to have to do something like
     * `$foo = some_custom_logic( get_post_meta( $post->ID, 'bar', true ) ); echo esc_html( $foo )`.
     * @param mixed  $value
     * @param int    $post_id
     * @param string $meta_key
     * @param int    $single   @todo handle the case where this is false
     * @return mixed
     *      `null` to instruct `get_metadata()` to pull the value from the database
     *      Any non-null value will be returned as if it were pulled from the database
    function add_dynamic_post_meta( $value, $post_id, $meta_key, $single ) {
    	$post = get_post( $post_id );
    	if ( 'page' != $post->post_type ) {
    		return $value;
    	switch ( $meta_key ) {
    		case 'verbose_page_template':
    			$value = "The page template is " . ( $post->_wp_page_template ?: 'not assigned' );
    	return $value;
  3. Skip to note 19 content

    Default Usage
    Get the meta for all keys for the current post:

    <?php $meta = get_post_meta( get_the_ID() ); ?>

    Get all meta for a single key for the current post:

    <?php $key_1_values = get_post_meta( get_the_ID(), 'key_1' ); ?>

    Get the first value of a meta key for the current post:

    <?php $key_1_value = get_post_meta( get_the_ID(), 'key_1', true ); ?>
  4. Skip to note 20 content

    Retrieve a Custom Field Thumbnail Url
    While you are in the WordPress Loop, you can use this code to retrieve a custom field. In this example, the thumbnail image url is in a custom field named “thumb”.

    <?php if ( get_post_meta( get_the_ID(), 'thumb', true ) ) : ?>
    	<a href="<?php the_permalink() ?>" rel="bookmark">
    		<img class="thumb" src="<?php echo esc_url( get_post_meta( get_the_ID(), 'thumb', true ) ); ?>" alt="<?php the_title_attribute(); ?>" />
    <?php endif; ?>
  5. Skip to note 21 content

    When you don’t specify a $key (”) and set $single to true in get_post_meta, it will return all keys still with an array of values.

    $meta = get_post_meta(get_the_ID(), '', true);
    //Array ( [key_1] =&gt; Array ( [0] =&gt; value_1 ), [key_2] =&gt; Array ( [0] =&gt; value_2 ) )
  6. Skip to note 23 content

    When we calling for all post meta, it will returned array value:

    $post_metas = get_post_meta(get_the_ID());

    sample output:

    array(2) {
      array(1) {
        [0]=> "value1"
      array(1) {
        [0]=> "val2"

    We can make it into string, array_column will resulting default array value into string, for sure we need array combine to re-form array key:

    $post_metas = get_post_meta(get_the_ID());
    $post_metas = array_combine(array_keys($post_metas), array_column($post_metas, '0'));

    now output will be like here:

    array(2) {
      string(6) "value1"
      string(4) "val2"
  7. Skip to note 26 content

    If the value of the $key parameter is falsy get_post_meta will return the entire post meta array, even if $single is set to true. for example:

    get_post_meta( $post_id, FALSE, TRUE); //Returns all the post meta fields as an array.
    get_post_meta( $post_id, '0', TRUE); //Will also return all the post meta fields as an array. 
  8. Skip to note 27 content

    Function The Retrieve a Number views in post

     Pass in function
    	1: PostID                      =>     use get_the_ID();
    	2: Meta Key Name               =>   'you can called anythings'
    	3: Get The Post Meta Field     =>   get_post_meta();
    	4: The Number Start Count      =>    add anyNumber ( 0,1,100,1000 or 2000 )
    	5: Count +1
    	6: Called Function in anypage  =>  <?php echo relationscode_save_post_views( ) ?>
     but you should remove (adjacent_posts_rel_link_wp_head)
    	function relationscode_post_views( ) {
           $postID = get_the_ID();
    	   $metaKey = 'relationscode_post_views';
    	   $views = get_post_meta( $postID, $metaKey, true );
    	   $count_start_num = 0;
    	   $count = ( empty( $views ) ? $count_start_num : $views );
           if(is_single()) {
        	  update_post_meta( $postID, $metaKey, $count );
        	  echo $count;
           } else {
        	   echo $views;
       remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );

  9. Skip to note 29 content

    Here’s a pitfall to steer clear of…

    register_post_meta() allows you to define a default value for a meta field. If the default value evaluates to true, you’ll be scratching your head why get_post_meta() returns true when you haven’t yet set a value, or just used delete_post_meta() .

    Obviously get_post_meta() will return the default value defined in register_post_meta() .

    register_meta( 'post', 'sample_field',[
    	'single'	=> true,
    	'type'		=> 'boolean',
    	'default'	=> true,
    if(!get_post_meta($post_id, 'sample_field', true)){
    	//This will now always execute unless you manually update the sample_field meta to false
  10. Skip to note 30 content

    False if post ID isn’t absint or is 0

    Passing $post_id == 0 (or anything not a absint) will return false no matter $single.

    $meta = get_post_meta( 0, 'key', true );
    var_dump( $meta ); // bool(false)
    $meta = get_post_meta( 0, 'key', false );
    var_dump( $meta ); // bool(false)

You must log in before being able to contribute a note or feedback.