4

The documentation from get_post_meta makes it sound as if the single argument will determine whether or not meta values are returned in an array or not. For example:

// If I set single to false, or leave it blank it's returned as an array
[my-meta] => Array
    (
        [0] => my-value
    )

// If I set single to true, it's returned as a string
[my-meta] = my-value

This works fine if I'm only returning data for a single meta key...but fails if I want to return all of the meta data, but return them all as strings (single).

It would seem that the proper call to get all of the meta values with string values would be:

$meta = get_post_meta( $transaction->ID, false, true );

But this returns with the array values and completely ignores the single value.

Why? Is there a way to get all of the meta data, but without the single element arrays? Those are unnecessary in my case.

EDIT: Just to clarify what I'm asking, I'd lie to get all of the meta like this:

array() {
    [my-meta-1] = my-value
    [my-meta-2] = my-value
    [my-meta-3] = my-value
    [my-meta-4] = my-value
}

Rather than like this (which is the only behavior I seem to be able to get):

array() {
    [my-meta-1] => Array
    (
        [0] => my-value
    )
    [my-meta-2] => Array
    (
        [0] => my-value
    )
    [my-meta-3] => Array
    (
        [0] => my-value
    )
    [my-meta-4] => Array
    (
        [0] => my-value
    )
}
4
  • Why would you want the value of all your meta fields concatenated in a single string? That is very weird and I think get_post_meta() is doing correctly by returning an array if no meta key is specified. Also, that behaviour is specified in the Codex (quoting codex): "If $single is set to true, the function returns the first value of the specified key (not in an array)"
    – cybmeta
    Jun 10, 2015 at 15:34
  • Hi @cybmeta, I've updated my question to make what I'm looking for more clear. I was not looking to concatenate them all :-).
    – Pete
    Jun 10, 2015 at 16:04
  • a single key can have multiple values, your desired format would break in that case, that's why it's formatted the way it is and not the way you want.
    – Milo
    Jun 10, 2015 at 16:08
  • In most cases I'm using this for custom meta keys on CPTs, where I only have a single value for each meta key, so it is what I want.
    – Pete
    Jun 10, 2015 at 16:09

2 Answers 2

4

This works fine if I'm only returning data for a single meta key...but fails if I want to return all of the meta data, but return them all as strings (single).

This doesn't make a lot of sense. A function in PHP can only return a single value so there is no way to return all meta as strings (plural). It has to come out as an array, or an object. And that is what the function does-- you get a single value as a string or you get an array. If you don't specify a key then the code has no way to know which key you want so you get them all, by defaurl not single. When you are not retrieving single values, WordPress does not collapse the nested array. If that is what you want, take it up with the Core developers on Trac. In the meantime, collapse the array yourself:

$meta = get_post_meta(350);
var_dump($meta);
foreach ($meta as $k => $v) {
  $meta[$k] = array_shift($v);
}

Or:

foreach ($meta as &$v) {
  $v = array_shift($v);
}

That may not bet he answer you hoped for, but I am pretty sure it is accurate. There might be a filter, but I doubt the effort would be worth it.

6
  • Thanks for the answer @s_ha_dum. I'm not sure my original questions intent was clear. I've updated it with (hopefully) a better explanation. I wasn't looking to somehow get a bunch of different values as a single variable :-P. Though your answer regarding collapsing the nested array is what I was after. I take it there's no simpler way to do this? I find that more often than not I don't want the value of each meta key to be in an array, which results in a lot of $meta['my-key'][0] type code. EDIT: I guess I could just write a custom get_post_meta_single function. Duh.
    – Pete
    Jun 10, 2015 at 16:06
  • Just implode the arrays created with the code above, or serialize or json_encode...
    – s_ha_dum
    Jun 10, 2015 at 17:28
  • Thanks! Yeah, I mean I know that there are numerous ways to add a couple of lines to take care of the issue. I was kinda thinking I'd like something that automatically took care of it. Still not sure why you can't specify single for an entire get_post_meta call--I don't know of any disadvantages that would have (seeing as how it would only do it when someone told it to).
    – Pete
    Jun 10, 2015 at 18:42
  • On the other hand, what you want strikes me as code bloat. I am pretty sure the use cases are very few.
    – s_ha_dum
    Jun 10, 2015 at 18:46
  • 1
    So, I think the question has been answered, yes?
    – s_ha_dum
    Jun 10, 2015 at 18:53
2

A short little function, perhaps:

function get_post_meta_single( $id ) {
  $m = get_post_meta( $id, false, true );    // get post meta as singles
  foreach( $m as &$v ) $v = array_shift($v); // collapse value array
  return $m;
}

As a side note, it's likely that the reason that WordPress doesn't collapse the array is to maintain consistency, so the same code can be reused for items with multiple values and single values. WordPress is all about the loop, remember.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.