10

I have been using transients a lot in WordPress since I discovered them, however to ensure my sites update properly when a post is edited or created I added a function to delete transients on post save.

This works great however I need to keep a list of all the transients I create throughout the site and then mention each one by name in my function.

This is especially troublesome when I name the transients automatically, for example some transients are named based on their post title.

Is there a way in WordPress to get a list of all the transients currently created on the site? I'd like to clear them all on post save. I'd like to do this whilst avoiding directly deleting the database entries (ie I'd like to use the delete_transient() function rather than just delete all the transients directly in the database).

4 Answers 4

10

The db query would look like this:

SELECT `option_name` AS `name`, `option_value` AS `value`
FROM  $wpdb->options
WHERE `option_name` LIKE '%transient_%'
ORDER BY `option_name`

To sort the results by their function (site transients, timeouts) use a function like this:

add_action( 'shutdown', function(){

    global $wpdb;
    $sql = "SELECT `option_name` AS `name`, `option_value` AS `value`
            FROM  $wpdb->options
            WHERE `option_name` LIKE '%transient_%'
            ORDER BY `option_name`";

    $results = $wpdb->get_results( $sql );
    $transients = array();

    foreach ( $results as $result )
    {
        if ( 0 === strpos( $result->name, '_site_transient_' ) )
        {
            if ( 0 === strpos( $result->name, '_site_transient_timeout_') )
                $transients['site_transient_timeout'][ $result->name ] = $result->value;
            else
                $transients['site_transient'][ $result->name ] = maybe_unserialize( $result->value );
        }
        else
        {
            if ( 0 === strpos( $result->name, '_transient_timeout_') )
                $transients['transient_timeout'][ $result->name ] = $result->value;
            else
                $transients['transient'][ $result->name ] = maybe_unserialize( $result->value );
        }
    }
    print '<pre>$transients = ' . esc_html( var_export( $transients, TRUE ) ) . '</pre>';
});

Now you get an array, separated by the transient functions with unserialized values.

Sample output:

$transients = array (
  'site_transient' => 
  array (
    '_site_transient_browser_0f2bbce5647f9c092edea85f1b5d9145' => 
    array (
      'platform' => 'Windows',
      'name' => 'Opera',
      'version' => '12.02',
      'update_url' => 'http://www.opera.com/',
      'img_src' => 'http://s.wordpress.org/images/browsers/opera.png',
      'img_src_ssl' => 'https://wordpress.org/images/browsers/opera.png',
      'current_version' => '11.64',
      'upgrade' => false,
      'insecure' => false,
    ),
    '_site_transient_browser_4155da8a3756e08080a06133476ef1fd' => 
    array (
      'platform' => 'Windows',
      'name' => 'Firefox',
      'version' => '19.0',
      'update_url' => 'http://www.firefox.com/',
      'img_src' => 'http://s.wordpress.org/images/browsers/firefox.png',
      'img_src_ssl' => 'https://wordpress.org/images/browsers/firefox.png',
      'current_version' => '16',
      'upgrade' => false,
      'insecure' => false,
    ),
  ),
  'site_transient_timeout' => 
  array (
    '_site_transient_timeout_browser_0f2bbce5647f9c092edea85f1b5d9145' => '1352809256',
    '_site_transient_timeout_browser_4155da8a3756e08080a06133476ef1fd' => '1366603648',
  ),
  'transient' => 
  array (
    '_transient_feed_mod_46583134dd8a90321b20eb41cdeb134c' => '1366089834',
    '_transient_feed_mod_57bc725ad6568758915363af670fd8bc' => '1352920456',
    '_transient_plugins_delete_result_1' => '1',
  ),
  'transient_timeout' => 
  array (
    '_transient_timeout_feed_46583134dd8a90321b20eb41cdeb134c' => '1366133033',
    '_transient_timeout_feed_57bc725ad6568758915363af670fd8bc' => '1352963656',
  ),
)
2
  • I think a combination of this, and naming my transients with a unique prefix as mentioned by @Milo, will give me what I need.
    – Shaun
    Jun 16, 2013 at 10:55
  • 5
    @Shaun: I know this question is old, but nonetheless: "Transients should also never be assumed to be in the database, since they may not be stored there at all.". If a caching plugin is in use, transients may be stored anywhere in the system - ranging from persistent on the disk to non-persistent in the memory (RAM). Therefore, directly querying the database is not advised. Instead you could have another transient, an array, which keeps track of all transient keys in use.
    – paolo
    Aug 14, 2016 at 18:12
3

You can query the database for all transients using something like:

global $wpdb;

// sorry about format I hate scrollbars in answers.
$your_transients = $wpdb->get_results(
             "SELECT option_name AS name, option_value AS value FROM $wpdb->options 
              WHERE option_name LIKE '_transient_%'"
          );

Or you can install this plugin.

http://wordpress.org/plugins/debug-bar-transients/

0

You can use the class wpdb to make a query in DB to get this info :

$query = "
SELECT * 
FROM wp_options
WHERE option_name LIKE  '_transient_%'
";

EDIT: use prepare() method if you choose to make query in database through wpdb

5
  • 1
    you don't need to prepare a query that doesn't take any input.
    – Milo
    Jun 15, 2013 at 18:08
  • I disagree with you.
    – JMau
    Jun 15, 2013 at 18:09
  • prepare prevents against injection, how do you inject a query that's entirely hardcoded in a string?
    – Milo
    Jun 15, 2013 at 18:17
  • prepare is absolutely needed for insert and update if the query accepts input. please explain why the query you've shown above needs to be sanitized. you wrote the query, there's nothing unknown being added to the query, it does not need to be prepared.
    – Milo
    Jun 15, 2013 at 18:27
  • You're right for insert and update, I was refering to another context. I always sanitize datas before querying.
    – JMau
    Jun 15, 2013 at 18:31
0

If you don't maintain a list, then there is no list. Core uses transients as well, so you'll need some way to identify your own, with some sort of unique prefix. You could then delete them all with a SQL query, like:

"DELETE FROM $wpdb->options WHERE `option_name` LIKE ('%YOUR-IDENTIFIER%')"

I can't speak to whether or not that's actually a good idea. You could safely delete them all and force core and all your plugins to recreate their transients, but that could be a hefty load depending on what was involved in creating them.

Your Answer

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

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