Login Register

Login Here

login

Register

Register

Working with post meta arrays

Post meta is data that is associated with a post. A post does not necessarily mean the default blog post type. Worpdress has 5 default post types: Post, Page, Attachment, Revision and Navigation Menu. These, any other custom post types, Comments and Users, all have a post meta table associated to them in the database. The post meta table consists of four columns; meta id, (post, comment or user) id, meta key and meta value. Each entry has a unique id, is associated with a parent post, comment or user and structurally consists of key value pairs. It is important to remember that wordpress meta data, like wordpress options are information stored as key and value.

MySQL does not store arrays. You cannot store an array data type in a MySQL field. Instead, you have to use your programming language, in this case PHP, to convert the array or object into a string representation of the data. JSON is a well known structure for doing just this. WordPress does not use JSON, however, for object representation. Instead, wordpress uses PHP’s serialize method which serializes objects in a string format that describes data based on type, quantity and value. I think it’s pretty clever actually, that an associative array such as this:


is parsed in a fashion such as this:

Where based on the count of the array, the parser identifies an associative array by grouping in twos.

The three methods we will be discussing today will be add, update and get post meta.

You’ll notice that add and update post meta have three common paramaters but the fourth is different. The first parameter is the id number of the post in question. This will typically be $post->ID in the loop. The second is the name of the meta key as a string and the third is the meta value you wish to assign to that meta key. Add post meta’s fourth parameter is called “unique” because you will provide a boolean value, true or false, indicating whether you want to allow more than one meta key in the databases meta field relative to this post, of the same name as the one provided. This means that if you have a key called “to_eat”, that key can be present in the database only once if you set unique to true. Or, if set to false, can be in the database as many times as you add it to the database, each with its own value associated to it.

For instance. If I have five food choices: “Seafood”,”Italian”,”Sushi”,”Organic”,”Greek”. I can have a key in the database for each of them titled “to_eat”.

1:to_eat = Seafood
2:to_eat = Italian
3:to_eat = Sushi
4:to_eat = Organic
5:to_eat = Greek

Because each of these keys, although having the same name, have unique id’s, they can be distinguished from one another.

The purpose for doing it this way is one, because meta is stored as key value pairs and two, querying. Because you can have a user interface for searching, filtering, etc… You will need to have a way of querying meta data associated with the post. WordPress’ meta query class allows for this, however, if you stored data as a serialized array:

You would have to filter the wordpress query and custimize it to query by way of regular expression looking for a %LIKE% pattern matching something to this effect: (type identifier, colon, number of, colon, quotation mark, string, quotation mark).

It’s not a very effective way of storing data for this type of querying.

To combat this issue and knowing full well that people would need a way to store different data with the same key, in resemblance of an array, wordpress provides this way of storing data with add post meta (or add user meta, etc…). So, before you begin creating methods for storing meta, you must first plan ahead and decide how you want to use that data later on. If it will be for use internally, options or settings for instance, then you can store data as an array and not worry about querying. If the data you are storing will be queryable and used for custom meta queries as a result of user action on the front end, you may want to strongly consider having multiples of the same key with the varying associated values.

It is necessary to discuss update versus add, post meta. Using update post meta, if the meta key does not already exist, the method will create it. This allows you to use update exclusively, disregarding add post meta and using update to both update and add. It is OK if you wish to do this as long as you have planned ahead and know what you are using it for. When using update post meta, you are sacrificing the ability to define whether the key you are adding will be unique. By default, the unique value is set to false, so you have now allowed for multiple keys of the same name to be added to the database (to the meta table associated with that post). This may get you in trouble if you deviate from your original plan of using update exclusively and then later use add post meta instead. Furthermore, update post meta will, if the fourth parameter is omitted, replace ALL existing values of ALL keys with the same name. So, if I have

1:to_eat = Seafood
2:to_eat = Italian
3:to_eat = Sushi
4:to_eat = Organic
5:to_eat = Greek

and I call update_post_meta(1,”to_eat”,”Pizza”);, My table will now look like this:

1:to_eat = Pizza
2:to_eat = Pizza
3:to_eat = Pizza
4:to_eat = Pizza
5:to_eat = Pizza

When using update post meta to update a meta value, you must make sure that you are either using and expecting only ONE meta key to be affected, OR you are providing the fourth parameter “PREVIOUS VALUE”. So, with the previous example, if I want to update only “Seafood”, I would have to do this: update_post_meta(1,”to_eat”,”Pizza”,”Seafood”);

The resulting table will look like so:

1:to_eat = Pizza
2:to_eat = Italian
3:to_eat = Sushi
4:to_eat = Organic
5:to_eat = Greek

To place an array into the database, you simply pass the array either directly or as a variable into the new value paramater. add/update_post_meta(1, “to_eat”, array(“Seafood”,”Italian”,”Sushi”,”Organic”,”Greek”)); or add/update_post_meta(1, “to_eat”, $myarray);. The array will be serialized and placed into the database as a serialized string representing the array.

Retrieval of the array, I believe, is what causes the most confusion. The purpose is because the “$single” parameter can seem a bit misleading. Let’s consider this:
$meta_values = get_post_meta(1, “to_eat”, $single);
If the data is stored not as an array but in the fashion of the previous examples, $single is a boolean value that is passed to define whether we want the result set to be returned as an array or as a single value. Single value infers that you will be getting a single string back based on the examples above. And that is correct in this case. So, if we passed $single = false, meaning that we do not want a single value, but rather, an array returned, wordpress will search the database and return a result set of all meta keys that match the passed parameter relative to the post id in question and return the result set as an array: $results = array(“Seafood”,”Italian”,”Sushi”,”Organic”,”Greek”).

If we set $single = true, meaning we want a single value returned. WordPress will pull only the FIRST value of the result set and give it to you. In this case, the first value is “Seafood” and that is what will be returned to you, as a string, because it is a string.

Before moving on, I would like you to think of $single = false as asking wordpress for an array and immediately, wordpress begins with $results = array(); So, as soon as you say, “I want an array back”, wordpress creates the array(). Now everything returned will be placed WITHIN the array(). Because we have five strings, the result set will be an array of five strings.

Add, update and get post meta (user meta, etc…) ALL deal with arrays by serializing or unserializing. So, if we pass an array, wordpress will serialize and place in the database. If we ask for data, regardless of whether we set $single to true or false, wordpress will parse the string if it is considered serialized and unserialize the data, returning it as an array (returning it just as it was passed in). With this in mind, let’s consider one meta key of “to_eat” with a value of the array of the five food types. It was passed as an array and in the database it looks like: “a:5:{i:0;s:7:”Seafood”;i:1;s:7:”Italian”;i:2;s:5:”Sushi”;i:3;s:7:”Organic”;i:4;s:5:”Greek”;}”.

In order to retrieve that data, we have to use the get method. In this case it’s a post so we’ll use get_post_meta. Now we have to decide whether we want to have a single value returned or an array. Thinking about it based on that last sentence alone, you would thing that we would have to pass $single as false because we want an array returned, but if we consider what I said before about thinking in terms of wordpress automatically creating an empty array and then placing the result set within that array, and also thinking about the fact that wordpress will automatically parse the serialized string and turn it into an array, then we might think again about what we need to set $single to. If single is set to false, wordpress will create an array: array(
Then parse the serialized string and place it into the result set within the encasing array: array(“Seafood”,”Italian”,”Sushi”,”Organic”,”Greek”)
).
So, what we get is a nested array. The only way to access data now, is by either looping through the first array or accessing it directly by index. Then we have to do the same with the inner arrays: $result[0][0], $result[0][1], etc…

In order to get the array, as a single array value, without an encasing array, we have to set the $single parameter to TRUE so that we get only one result. This will give us: array(“Seafood”,”Italian”,”Sushi”,”Organic”,”Greek”), which is exactly what we want in this case.

So, now we know how wordpress stores meta data into the database and how it retrieves that data. Hopefully this clears up any confusion about storing and retrieving post meta arrays, user meta arrays and the like.

I'm a wordpress developer. I am admin of this site and hope everyone finds something of use for their own projects or learning.


0 comments on “Working with post meta arrays

Join Discussion