WordPress for the adventurous: Options API

As WordPress developers, we often need a way to store and retrieve data. The most common reason for that is that we need to store and retrieve settings for our plugin or theme. But the reality is that there are countless of other reasons why you’d need to store and retrieve data.

So how do we do it? Well, the primary tool that we have at our disposal to do this is the options API. It’s an API that offers a way for us to store and retrieve data from the WordPress database.

It’s pretty much as indispensable as the plugin API. We often can’t build anything in WordPress without it. That’s why it’s worth looking a bit deeper at how it works.

The wp_options table

At its core, the options API is an API that lets us interact with the wp_options database table. With it, we can add, remove and update values stored in the database table. The database table itself has four columns: option_id, option_name, option_value and autoload.

option_id is the primary key of the wp_options table. It autoincrements each time that MySQL adds a new row to the table. But, in practice, WordPress doesn’t use it for anything.

The two important columns of the wp_options table are the option_name and option_value columns. WordPress uses these two columns as a key-value pair. This is a form of data representation where we assign data to a key. PHP associative arrays work the same way.

The options API doesn’t expect you to use option_id to retrieve your data. In fact, it doesn’t even let you use it. What it wants is for you to always use a key to store your data. And you use that same key to retrieve it.

The last column of the wp_options table is the autoload column. This is a flag used to determine whether WordPress will autoload an option or not. The flag should be one of two values: yes or no.

On option autoloading

So what’s special about autoloading an option? Well, let’s imagine that you need to know the value of a specific option. You’ll use the options API to fetch that option from the database. And, to do that, WordPress will need to perform a SQL query.

Now, let’s say that you need another option. WordPress will need to query the database one more time to get it. Making SQL queries over and over like that doesn’t scale well at all.

So to solve this problem, WordPress created the concept of autoloaded options. WordPress will load all options that have the autoload flag set to yes in memory. This reduces the number of SQL queries that WordPress needs to do to fetch options from the database.

From a code perspective, the wp_load_alloptions function is in charge of loading all the autoloaded options. In practice, you shouldn’t need to ever use this function. Every time that you use the options API it will call the wp_load_alloptions function if it needs to load all the autoloaded options.

API functions

Alright, this pretty much covers everything surrounding the wp_options table in the database. Next, let’s look at the options API functions themselves. We’re going to group them into four categories: adding, deleting and getting and updating options.

Types of API functions

First, it’s worth noting that each options API function comes in two types: regular and multisite. The regular functions are the ones that most of us use. They interact with the wp_options table that we just discussed.

Meanwhile, the multisite versions all have _site_ in their name. All multisite options API functions behave more or less the same as their regular counterpart. But they do have two architectural differences that are worth pointing out.

The biggest difference is that multisite functions don’t use the wp_options table. They use a different table called wp_sitemeta. It’s a table that stores options for entire blog networks.

The other difference is that site options (as we call them) are all autoloaded whether you want to or not. You don’t have a flag that you can set to control whether WordPress will autoload them or not. This might seem like a big change, but it’s not.

The reality is that most of the time we don’t overwrite the default autoload flag. We leave it as is. This which means that WordPress will autoload most of the options that we add anyways.

What if I don’t know which one to use?

Having to think about which type of functions to use can be annoying. That’s why there’s a third lesser known type of functions that you can use instead of the two that we’ve seen. These are the network option functions.

Like the multisite functions, the network functions have _network_ in their name. But, unlike the other two types of options API functions, the network ones don’t interact with a specific database table. They will pick whether to use the wp_options or wp_sitemeta table based on whether WordPress is using multisite or not.

Using these functions can be useful if you’re not sure which type of function to use. They’ll ensure that there’s only one set of options for your plugin whether someone is using multisite or not. So you should keep those functions in mind for those situations.

That said, the rest of this article will focus on the regular and multisite types of functions. That’s because these are the functions that you’ll use the most. They’re also the ones that interact with the WordPress database tables.

Adding an option

The first set of functions that we’ll see deal with adding new options. You have the add_option which adds a new option to the wp_options table. It uses four parameters: option, value, deprecated and autoload.

Most of these parameters fit what we’ve talked about so far about the options API. option is the name of the option that we want to add. Meanwhile, value is the value of that we’ll store in the wp_options table.

This third parameter is deprecated (thus the name!) so you should always pass it an empty value. The last parameter is autoload. This is the autoload flag that we’ve been talking about where the default value is yes.

The other function that we have is the add_site_option function. It adds a new option to the wp_sitemeta table. It uses two parameters: option and value. These two parameters are the same as the ones used by the add_option function.

Both functions return a boolean value. If the function managed to add the option, the function will return true. Otherwise, it’ll return false.

Deleting an option

Next up are functions that we use to delete options. You have the delete_option to delete an option from the wp_options table. The other function is delete_site_option which deletes an option from the wp_sitemeta table.

Both functions only use one parameter. It’s the name of the option that we want to delete. They also return a boolean value like the previous functions did. The return value will be true if the function deleted the option and false if it didn’t.

Getting an option

After deleting an option, let’s look at the functions that you can use to get an option. As usual, we have two functions: get_option and get_site_option. The first one is for the wp_options table and the other is for the wp_sitemeta table.

Both functions use two parameters: option and default. option is the name of the option that we’re trying to get. If the functions find a value using the option parameters, they’ll return it. Otherwise, they’ll return the value that you passed as the default argument of the functions.

Updating an option

Last are the functions that we use to update an existing option in WordPress. We have the update_option for the wp_options table. And the update_site_option function for the wp_sitemeta table.

Both functions use similar parameters. They both use option and value parameters. option is the name of the option that we want to update. Meanwhile, value is the new value that we’re going to assign to the existing option.

That said, the update_option function also has a third parameter: autoload. This parameter lets you update the autoload flag of an option as well as the value. update_site_option doesn’t use that parameter because the wp_sitemeta doesn’t use the autoload flag.

Both functions return a boolean value. The function will return true when WordPress updated the option. Otherwise, it’ll return false.

Updating an option that doesn’t exist

But what happens if we try to update an option that doesn’t exist? In that scenario, both functions will call either the add_option or add_site_option functions. This is an important (if not the most important) thing to know about the options API.

It means that, in practice, you don’t need to use the functions to add a new option. Instead, you can just use the update functions for both adding and updating an option. This simplifies your code around these two operations.

That’s because the functions that let you add an option only work if the option doesn’t exist already. So you need to add a conditional statement to check if an option exists already if you’re going to use them.

But this isn’t necessary if you use the update option functions everywhere. So feel free to do that in your code. There’s no reason not to.

Actions and filters

Now that we’ve covered all the functions that make up the options API. Let’s talk a bit about the actions and filters that you can use with it. We’re not going to look at them all because that’s a bit excessive. (And not super useful either.)

Dynamic hooks

Here’s what’s important to know. First, every options API function uses at least one dynamic action or filter. This is an action or filter with a name that follows the format: hook_name_$option.

These actions or filters allow you to target an option with a specific name. Without them, you’d have to use generic actions or filters that don’t use the option name. And then you’d have to check the option name each time WordPress calls your action or filter option.

Hook timing

The other important thing to know is the timing surrounding actions and filters. All option API functions have actions and filters before and after interacting with an option. This gives you another angle for targeting options using the plugin API.

For example, you can short-circuit the process of getting an option with the get_option function. Using the pre_option_$option filter, you can pass an option value without even querying the database. This is useful if you want to enforce a specific value for an option.

The WordPress hard drive

So that wraps up our look at the options API! As you saw, it’s a pretty small API. But don’t let its size fool you. It does a huge amount of work for WordPress.

As WordPress developers, we’re in constant contact with it. It’s a good reason to know all the little details about it. That way, you can use it to its full potential.