We’ve covered the reasons why using transients (and caching in general) can greatly enhance the performance of WordPress sites. I’m offering up what I find to be two compelling solutions for pain points that are often encountered when working with transients–how to create dynamic keys and delete transients in bulk.
Creating Dynamic Keys
Let’s say I have a function that accepts an array of three arguments and tries to get a transient that is specific to those parameters. If found, the transient’s data will be used. If not, the data will be regenerated. One common way to do this is as follows (see line 24 in particular):
[snippet slug=creating-dynamic-transient-keys-1 lang=php]
This results in dynamically created transient keys such as wds_post_count_post_2016-1-1_2016-7-1.
This technique is potentially problematic if you have values with spaces in them, arrays, or values such as true, false, or null. Extra checks would have to be in place to account for those possibilities and convert those values to something that can be used in the transient key every time we get, set, or delete it. Doing so can become messy and unwieldy–and the transient keys become longer and longer the more arguments you add to them. We can forego those unnecessary complications by replacing the code on line 24 with the following, instead:
$post_count = get_transient( 'wds_post_count_' . md5( serialize( $args ) ) );
serialize() will create a storable representation of a value, then passing that to md5() will create a unique hash of the data that’s always exactly 32 characters. Best of all, we can pass our entire $args array to those functions without the need to break out, validate, and add each of its values to the transient key individually. This results in keys such as:
wds_post_count_B3A076241698F988761FA618286DF384
Technically speaking, you could get rid of the wds_post_count_ prefix, but I recommend leaving it in so that part of the key is still human-readable and provides an indicator of what data it stores. Another bonus: If you’re using a GUI tool to view the database, you can sort the wp_options table by the option_name column, and all options with the name _transient_wds_post_count_* will be grouped together and easy to locate.
A complete example showing how to use serialize() and md5() when getting and setting transients is below.
[snippet slug=creating-dynamic-transient-keys-2 lang=php]
Deleting Transients in Bulk
If you’ve ever used WordPress’ wp_cache_* functions to set and get data using the object cache, you know that the $group parameter can be used to assign cached data to a group, then wp_cache_delete() can be used to easily delete the cached data within that group. Handy! When working with transients, we have no such luxury. Because of this, it’s common practice to loop through all possible key permutations, calling delete_transient() each time, like this:
[snippet slug=deleting-transients-bulk-1 lang=php]
As you can see, having several nested loops in place just to make sure all transient values are deleted is cumbersome, and can be prone to error in the event that even one permutation of the transient key isn’t accounted for. Instead of all of that, wouldn’t it be nice to just be able to delete all transients whose keys begin with wds_post_count? One of our resident WDS code wizards, Parbs, devised the set of functions below that can be used for just such a purpose.
[snippet slug=delete-transients-key lang=php]
So putting those to use to delete our transients for this example would look something like this:
[snippet slug=delete-transients-bulk-2 lang=php]
Quite a bit shorter and easier, eh?
Two words of caution:
- Since these functions search for and delete all transients that begin with the prefix you provide, make sure that you don’t have any other transient keys that begin with the same thing. For instance, if I were to save data with transient keys like
wds_post_count_*andwds_post_count_featured_*, those would both be deleted if I were to callwds_delete_transients( 'wds_post_count' ); - Because the
wds_search_database_for_transients_by_prefix()function searches the database for transients, it can’t be used on sites that have a persistent object cache in place. If a persistent object cache is being used, transients are stored in memory rather than in the database. So on those sites, you should delete transients using the full keys instead, such asdelete_transient( 'transient_key_param1_param2' ).
Have any more?
I hope incorporating the techniques outlined in this post is as helpful for you as it has been for me when working with transients. Do you have some others? Let us know in the comments.
