Leave a Reply

3 comments

  1. update_post_meta() calls update_metadata which begins with this line:

    if ( !$meta_type || !$meta_key )
        return false;
    

    I wrote a simple test (with a lot of cut & paste) to see how string values of 0 are evaluated (instead of looking it up in the PHP manual):

    <?php
    
    $meta_key = (string) 0;
    
    if ( ! $meta_key )
        echo "0 exits function<br />";
    
    else {
        echo "0 remains in function<br />";
        echo "&nbsp;&nbsp;$meta_key = $meta_key<br />";
        echo "&nbsp;&nbsp;(integer) $meta_key = " . (integer) $meta_key . '<br />';
    }
    
    echo '<br />';
    $meta_key = (string) 0;
    
    if ( ! $meta_key )
        echo "(string) 0 exits function<br />";
    
    else {
        echo "(string) 0 remains in function<br />";
        echo "&nbsp;&nbsp;$meta_key = $meta_key<br />";
        echo "&nbsp;&nbsp;(integer) $meta_key = " . (integer) $meta_key . '<br />';
    }
    
    echo '<br />';
    $meta_key = (string) '0';
    
    if ( ! $meta_key )
        echo "(string) '0' exits function<br />";
    
    else {
        echo "(string) '0' remains in function<br />";
        echo "&nbsp;&nbsp;$meta_key = $meta_key<br />";
        echo "&nbsp;&nbsp;(integer) $meta_key = " . (integer) $meta_key . '<br />';
    }
    
    echo '<br />';
    $meta_key = 0x0;
    
    if ( ! $meta_key )
        echo "0x0 exits function<br />";
    
    else {
        echo "0x0 remains in function<br />";
        echo "&nbsp;&nbsp;$meta_key = $meta_key<br />";
        echo "&nbsp;&nbsp;(integer) $meta_key = " . (integer) $meta_key . '<br />';
    }
    
    echo '<br />';
    $meta_key = (string) 0x0;
    
    if ( ! $meta_key )
        echo "(string) 0x0 exits function<br />";
    
    else {
        echo "(string) 0x0 remains in function<br />";
        echo "&nbsp;&nbsp;$meta_key = $meta_key<br />";
        echo "&nbsp;&nbsp;(integer) $meta_key = " . (integer) $meta_key . '<br />';
    }
    
    echo '<br />';
    $meta_key = '0x0';
    
    if ( ! $meta_key )
        echo "'0x0' exits function<br />";
    
    else {
        echo "'0x0' remains in function<br />";
        echo "&nbsp;&nbsp;$meta_key = $meta_key<br />";
        echo "&nbsp;&nbsp;(integer) $meta_key = " . (integer) $meta_key . '<br />';
    }
    
    echo '<br />';
    $meta_key = (string) '0x0';
    
    if ( ! $meta_key )
        echo "(string) '0x0' exits function<br />";
    
    else {
        echo "(string) '0x0' remains in function<br />";
        echo "&nbsp;&nbsp;$meta_key = $meta_key<br />";
        echo "&nbsp;&nbsp;(integer) $meta_key = " . (integer) $meta_key . '<br />';
    }
    

    The result was:

    0 exits function
    
    (string) 0 exits function
    
    (string) '0' exits function
    
    0x0 exits function
    
    (string) 0x0 exits function
    
    '0x0' remains in function
      $meta_key = 0x0
      (integer) $meta_key = 0
    
    (string) '0x0' remains in function
      $meta_key = 0x0
      (integer) $meta_key = 0
    

    So, to add a value of 0 you could change it to the string ‘0x0’ and cast it to integer when retrieving it. 0x0 is binary (I think) for 0.

  2. PHP treats 0 as equivalent to false for comparisons. Because the update_post_meta function checks for a value before saving, it’s exiting because 0 == false.

    You could do something like this before saving the post meta, it’s a bit hacky but it would work:

    if ( 0 === $value ) {
        $value = 'zero';
    }
    

    Then when you’re retrieving your values later, you just do the opposite:

    $value = get_post_meta( $post_id, 'meta-key', true );
    if ( 'zero' == $value ) {
        $value = 0;
    }
    
  3. The issue is to do with this part of update_metadata() function within meta.php that update_post_meta() calls

    $result = $wpdb->update( $table, $data, $where );
    if ( ! $result )
        return false;
    

    As the return value is 0 then the if statement correctly treats it as false, albeit 0 has been saved to the database.

    This only happens when it updates. If a new post meta is added with a value of 0 then it returns the line id as expected.