Drupal - Is there a way to hook on cache clearing?

The way to do this is to use hook_flush_caches in combination with register_shutdown_function. Example code:

/**
 * Implements hook_flush_caches().
 */
function mymodule_flush_caches() {
   // After caches are cleared we will run mymodule_cache_rebuild()
   register_shutdown_function('mymodule_cache_rebuild');

   // We don't want to add any custom cache-tables, so just return an empty array
   return array();
}

/**
 * Rebuild expensive cache items that need to be rebuilt immediately.
 */
function mymodule_cache_rebuild() {
  // Do the cache rebuild work here
}

Using register_shutdown_function means that our cache-rebuilding function will be called after the caches have been cleared. We are abusing hook_flush_caches in a way that it was never intended to be used, but this should do exactly what you need.


No, there isn't. Not really. At least not in 6 or 7. Assuming 7:

If you will look at drupal_flush_all_caches() you will see it invokes hook_flush_caches(). This hook is meant to:

"add cache table names to the list of cache tables that will be cleared by the Clear button on the Performance page or whenever drupal_flush_all_caches is invoked."

It would be tempting to simply make your module's hook go last and write code there. But let's look again at drupal_flush_all_caches(). Actual deletion happens like this:

  $cache_tables = array_merge(module_invoke_all('flush_caches'), $core);
  foreach ($cache_tables as $table) {
    cache_clear_all('*', $table, TRUE);
  }

It means that all hooks are fired before anything gets really cleared. There is only one function called after actual deletion, _system_update_bootstrap_status(), but it only calls hook_boot, hook_exit, hook_watchdog and hook_language_init - hooks you don't want to implement only to provide cache-clear-dependant functionality.


Broad strokes here:

While there isn't a hook out there in pre-D8, you could write your own database backend based upon the standard DrupalDatabaseCache one and then write any or all sorts of logic into your clear() function. A quick look would suggest this to be a reasonably straightforward in D7 (just copy the class to your custom name and modify it etc by throwing in a module_invoke_all() as appropriate) and with the cache_backport module would even work in D6. Then point any cache bins you want fancified on clear and you should be on your way.