If you work with WordPress you’ve most likely worked with its options. The WordPress Option API is pretty self explaining and easy to use. The WordPress Transient API is a little less known but also a powerful API that’s definitely worth taking a look at if you’ve never heard of it before.
If you look at the Codex page for the
add_option function and look at the Parameters you find the following description for the first parameter:
(string) (required) Name of the option to be added. Must not exceed 64 characters. Use underscores to separate words, and do not use uppercase—this is going to be placed into the database.
The most important part of the description is ‘Must not exceed 64 characters’, they should make this bold and uppercase. What happens when your
$option (key) exceeds 64 characters? It’s truncated to fit, saving the option with a different key than you’ve set as parameter. This results in not being able to retrieve an option with the same key as you’ve set it if the key exceeds 64 characters.
A small example of how this can go wrong:
I understand the need of a maximum length on the option key but there’s no error or notice when the key exceeds 64 characters. This can cause some serious hard to track down bugs.
Transients, like options, also have a maximum character key length and like the options there’s also no error or notice when exceeding this length. The maximum length for transients differs to the maximum length of options though, there’s even a difference between expiring and non expiring transients. The key of a transient that doesn’t expire has a maximum length of 53 characters. The key of a transient that does expire has a maximum length of 45 characters. Please note the difference between the two because when you attempt to set an expiring transient with a key length between 46 and 53 characters, the transient will store but will be deleted before it can be returned by
get_transient due to the missing
Like I’ve showed in the option example above, if you try to store a transient with a key longer than it’s maximum character length, the key will be truncated to fit. This results in the transient being saved with a key different that the key in your code. For transients this is especially tricky because transients are often used to store something for a longer period of time and validate it at some point in the future. So you add a transient by using
set_transient, the function will return
true and you think everything works. Then when you check your transient in the future, it’s not there. Annoying bugs to track down, very annoying bugs to track down.
A transient key length gone wrong example
Imagine having a WordPress plugin that contacts your own server to log some settings*. Let’s say we do this on an admin page load with a maximum of once every 4 hours. To ensure we only do this once every 4 hours, we use a transient. We generate the transient key automatically based on our plugin slug appended by ‘last_logged’, to ensure we’ve got a unique key and prevent conflicts with other plugins. The problem, this automatically generated key exceeds the maximum transient length and is therefor saving with a different key than the key that’s in your code. So what will this easy to make error result in? It will result in your server being contacted on every admin page load, terrible for the performance of the plugin and when implemented in a populair plugin close to a DDOS attack on your own server.
* This is known as phoning home, only do this opt-in.
There’s a 4 year old Core Trac ticket that identifies this problem and offers a solution. The patch adds a validation to both functions that check the length of the key and displays a warning when they’re exceeded. The ticket is (again) pretty active so fingers crossed this will make it into Core one day.
Using options and transients and not sure what the length of the keys are you’re using? Be sure to check them! I hope this helps any one out reading this. Missing something? Found a problem? Got an improvement? Please let me know in the comments below.