0

I am trying to save some numbers into the posts as a custom field in different times. I want to store an array that includes selected numbers for each posts. But I can't update the current values (custom field array). Here are my codes:

$new_number = $_POST['number'];
$old_numbers = get_post_meta( $post_id, 'numbers', false );

if( empty( $old_numbers ) ){
    add_post_meta( $post_id, 'numbers', $new_number );
}else{
    array_push( $old_numbers, $new_number );
    update_post_meta( $post_id, 'numbers', $old_numbers );
}

But it's not working. The stored array (serialized) is being wrong format. I couldn't find any solution for this. How can I achive this?

2
  • you shouldn't store PHP serialised data, it opens you up to PHP object deserialisation attacks. implode and explode are more than enough for what you need, and make it human readable. json_encode and json_decode also work better
    – Tom J Nowell
    Commented Jun 26, 2018 at 22:00
  • Serialized data is up to WordPress, when you store post meta values like arrays them are converted by WordPress into a serialized string.
    – guido
    Commented Jun 27, 2018 at 10:55

1 Answer 1

2

That is because you are passing false as the third parameter, that means you are retrieving all of the meta with the same key.

The first time you store the value, the meta doesn't exist and the value is stored into the DB as a string, the second time you store the value serialized that is the only time the value will be retrieved as an array with the values inside the single array.

The third time you'll receive an array of array with the first to values stored within the first array and the third value within another index but outside of the first array.

To be more clear.

[
  [
    0 => 'a', 
    1 => 'b',
  ]
  [
    0 => 'c',
  ]
]

If you want to store your data within the same value you have to pass true as the third parameter and also, I suggest to pass true as the fourth parameter for add_post_meta so you make that post meta unique.

In any case just to be sure you retrieve always an array I would suggest to cast and filter the retrieved value.

So the first time the value converted to an array will be an array with one value 0 because get_post_meta will return false.

If you filter the array you'll we'll have only the right values. Be aware btw, that values that can be evaluated as false can be stripped out of the meta.

So if you think you'll have 0 as the value of your meta don't use the array_filter.

$new_number = $_POST['number'];
$old_numbers = array_filter((array) get_post_meta( $post_id, 'numbers', true ));

if( empty( $old_numbers ) ){
    add_post_meta( $post_id, 'numbers', $new_number, true );
}else{
    array_push( $old_numbers, $new_number );
    update_post_meta( $post_id, 'numbers', $old_numbers );
}

Instead:

$new_number = $_POST['number'];
$old_numbers = get_post_meta( $post_id, 'numbers', true );

if( ! $old_numbers ) {
    $old_numbers = [];
}

if( empty( $old_numbers ) ) {
    add_post_meta( $post_id, 'numbers', array($new_number), true );
} else {
    $old_numbers = array_merge((array) $old_numbers, (array)$new_number);
    update_post_meta( 1, 'numbers', $old_numbers );
}

Extra, isn't always a good idea to directly use $_POST values, use filter_input or filter_var to prevent tainted values to be stored in the DB.

5
  • I’m sorry, but it won’t work, I guess... If old_numbers does not exist, you assign an empty array to it. Then you check if it’s empty and if so, you save the number as meta field, and if treat the value as an array. But you saved a number in there at the first time, so it won’t be an array, so you can’t do array_push... Commented Jun 26, 2018 at 22:10
  • That works tested, if the post meta doesn't exists it return false but we want to have an array, so if the meta doesn't exists we make $old_numbers an empty array, so the add_post_meta is called, it store the new value and when we'll retrieve it the second time we'll convert to an array (see the cast when calling get_post_meta).
    – guido
    Commented Jun 27, 2018 at 10:57
  • Well, take a look at your code again. You get post meta and store it in $old_numbers. You check if it's false and assign empty array to it. Then you check if it's empty (so yes, it is empty, you've just assigned an empty array to it) and if so, you save $new_number (which is just a number) as post meta... Commented Jun 27, 2018 at 11:01
  • @KrzysiekDróżdż Updated the code you were right. Thanks
    – guido
    Commented Jun 27, 2018 at 15:26
  • Problem is solved. Thank you so much for all comments :) Commented Jul 5, 2018 at 21: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.