How do I save each option in a multiple select menu as it's own meta_key + meta_value pair?

This is the basic multiple select menu. Note: multiple select menus allow you to select more than one option.

<select name="products[]" multiple>
    <option value="1">Product One</option>
    <option value="2">Product Two</option>
    <option value="3">Product Three</option>
    .... etc

The bit of code inside the save_post function that I need help with.

if ( isset( $_POST[ 'products' ] ) ) {
    foreach ( $_POST[ 'products' ] as $product ) {
        // this would just keep adding the products as separate meta keys, which is what I want, but I need to modify it so it deletes them when they are unselected.
        add_post_meta( $post_id, 'products', $product, false );

I'd like each option to be it's own meta key and value pair and not a serialized array. If the multiple select menu is updated I'd like old values no longer selected to be removed from the postmeta table with delete_post_meta.

For example, the wp_postmeta table would look like this:

post_id     meta_key             meta_value
45          products             2
63          products             3
12          products             1

1 Answer 1


Try this inside save_post but please note the code is not tested

$old = get_post_meta($post_id, 'products');
$new = isset ( $_POST['products'] )  ? $_POST['products'] : array();
if ( empty ($new) ) {
   // no products selected: completely delete alla meta values for the post
   delete_post_meta($post_id, 'products');
} else {
  $already = array();
  if ( ! empty($old) ) {
    foreach ($old as $value) {
      if ( ! in_array($value, $new) ) {
        // this value was selected, but now it isn't so delete it
        delete_post_meta($post_id, 'products', $value);
      } else {
        // this value already saved, we can skip it from saving
        $already[] = $value;
  // we don't save what already saved
  $to_save = array_diff($new, $already);
  if ( ! empty($to_save) ) {
    foreach ( $to_save as $product ) {
       add_post_meta( $post_id, 'products', $product);

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.