WordPress postmeta quirks

While trying to iron out some XML export issues on random WordPress sites, I stumbled across some interesting (and inexplicable) design choices:

Keys don’t get sanitized

The meta_key does not get sanitized with sanitize_key(), i.e., it can contain almost any character including spaces. As far as I can tell, only wp_unslash() gets applied to the key. This also leads to multiple filters and actions including spaces.

Multiple meta entries with the same key

You can add multiple entries with the same key. The documentation for add_post_meta() even says so:

Note that if the given key already exists among custom fields of the specified post, another custom field with the same key is added unless the $unique argument is set to true, in which case, no changes are made

This allows us to add multiple meta entries with the same key:

Getting values

get_post_meta(5, '_Google Plus_shares') returns an array with all three values:

array(3) {
  string(9) "value one"
  string(9) "value two"
  string(11) "value three"

Setting the $single parameter to true get_post_meta(5, '_Google Plus_shares', true) only returns the first value. Everything fine here, the $single parameter makes more sense to me now. I still wish the default was true.

Setting values

If you have multiple post meta entries with the same key, you’ll have to use the $prev_value parameter on update_post_meta(), to signal which entry to update. Otherwise, all values will be updated with the same value.