Problem storing arrays with update_user_meta

I am writing a function that adds an ID number to an array and puts the array in the usermeta. $_GET['auction'] is the post_id.

Below is the function:

Read More
$reminders = get_user_meta( $current_user->ID, "reminders" );
print_r( $reminders );
if( in_array( $_GET['auction'], $reminders ) ) {
    echo "Failed: Auction already in list";
} else {
    array_push( $reminders, intval( $_GET['auction'] ) );
    if ( update_user_meta( $current_user->ID, "reminders", $reminders ) ) {
        echo "Success";
    } else {
        echo "Failed: Could not update user meta";
    }
}
print_r( $reminders );

Here is the output after adding one auction:

Array ( ) 
Success
Array ( [0] => 7 ) 

Here is the output after adding two auctions:

Array ( [0] => Array ( [0] => 7 ) ) 
Success
Array ( [0] => Array ( [0] => 7 ) [1] => 73 )

And here is the output after adding three auctions:

Array ( [0] => Array ( [0] => Array ( [0] => 7 ) [1] => 73 ) ) 
Success
Array ( [0] => Array ( [0] => Array ( [0] => 7 ) [1] => 73 ) [1] => 0 )

Notice that adding a new element to the array using array_push works fine. But when the array is stored in the usermeta then retrieved again, the last element in the array has been put into an array of its own, creating an infinitely dimensional array. I’d prefer to keep this array one dimensional.

Is there a way I can run update_user_meta and get_user_meta without it changing the structure of my array?

Related posts

Leave a Reply

5 comments

  1. Haven’t used the function for quite a time, but i guess your problem is that you are pushing an array into an array. So check if intval($_GET['auction']) is an array:

    echo '<pre>';
    print_r(intval($_GET['auction']));
    echo '</pre>';
    

    Edit #1: You maybe need to get the value from that array and then array_push it. So maybe something like array_push( $reminders, $_GET['auction'][0]) ); – if you’re only adding one single value. You could also do something like $reminders[] = $_GET['auction'][0]; to add it to the end of your array.

    Edit #2: From a look at the core file: yes. update_user_meta() is just an alias of update_metadata() which takes the ID + the value and puts it into the database as and array.

    // From /wp-includes/meta.php ~ line 135
    $where = array( $column => $object_id, 'meta_key' => $meta_key );
    
    if ( !empty( $prev_value ) ) {
        $prev_value = maybe_serialize($prev_value);
        $where['meta_value'] = $prev_value;
    }
    
  2. I had the same problem. Adding “true” to “get_user_meta” worked for me. For example:

    FROM:

    $reminders = get_user_meta($current_user->ID,"reminders");
    

    TO:

    $reminders = get_user_meta($current_user->ID,"reminders",true);
    
  3. Had the same issue and resolved it with this little bit, which puts all new values in a single array saved as the user meta data:

    //Where $access_key is the next (added) value
    
    $get_access_keys_from_wp = get_user_meta($user_id,'wsm_capability');
    $current_access_keys = $get_access_keys_from_wp[0];
    $new_access_keys = array();
    $new_access_keys[]=$access_key;
    
    foreach($current_access_keys as $key => $value){
        $new_access_keys[]=$value;
    }
    delete_user_meta( $user_id, 'wsm_capability');//Clear out the meta data...
    update_user_meta( $user_id, 'wsm_capability', $new_access_keys);
    

    Array before save/update for meta key (from get_user_meta):

    Array
    (
        [0] => access_9
    )
    

    Resulting Array (after meta update) adding value of ‘access_5’:

    Array
    (
        [0] => access_5
        [1] => access_9
    )
    

    If you need the new value to be added to the end of the array, do this instead:

    //Where $access_key is the next (added) value    
    $get_access_keys_from_wp = get_user_meta($user_id,'wsm_capability');
    $current_access_keys = $get_access_keys_from_wp[0];
    $new_access_keys = array();
    
    foreach($current_access_keys as $key => $value){
        $new_access_keys[]=$value;
    }
    $new_access_keys[]=$access_key;
    

    Then update the meta…

    Bryan

  4. It seemed that the problem was with serializing/unserializing the array, so I just rewrote the function to be a comma sperated string:

            $reminders = get_user_meta($current_user->ID,"reminders",TRUE);
            if(is_int(strpos($reminders,$_GET['auction']))) {
                echo "Failed: Auction already in list";
            } else {
                $reminders .= ",".intval($_GET['auction']);
                if(substr($reminders,0,1) == ",") { //Remove leading comma if it exists
                    $reminders = substr($reminders,1,strlen($reminders)-1);
                }
                if(update_user_meta($current_user->ID,"reminders",$reminders)) {
                    echo "Success";
                } else {
                    echo "Failed: Could not update user meta";
                }
            }
    
  5. Shaun’s answer was correct but I feel needs more clarification. You can put in an array into a user meta entry but when you retrieve it you still need to retrieve it with the single argument set to true or else you get an array of an array back. Here is my code:

    $past_orders = get_user_meta($order_userID, 'qr-replacement-orders',true);
    
    //see if this new order has already been processed
    if(in_array($_GET["oid"],$past_orders))
    {
         echo '<p>This order has already been processed.</p>';
        //debug
        //var_dump($past_orders);   
    }
    else
    {
          //add the order number to the array of past orders and store it
         //if list is empty, initialize it to empty array
         if($past_orders == '')
         {
            $past_orders = array();
         }
         //add the new order to the list
        array_push($past_orders, $_GET["oid"]);
    
        //add the new list to the DB
        update_user_meta($order_userID, 'qr-replacement-orders',$past_orders);
    
        echo '<p>Your card has been purchased and will be sent to you in the mail.  Thanks!</p>';                       
    
        //debug: confirm it worked
        //$past_orders = get_user_meta($order_userID, 'qr-replacement-orders',true);
        //var_dump($past_orders);   
    }