How to stop PHP code output from caching in Drupal 8

But what if we want Drupal 8 caching to be LESS awesome?
But what if we want Drupal 8 caching to be LESS awesome?

Drupal 8 caching is awesome. I get it, and thank you to the community for that awesomeness.

For those of you wondering why your PHP code (probably entered into a block or a node using the PHP Input Filter) will not execute without clearing the cache in-between runs, this information is for you.

Early in Drupal 8 beta we were able to do things like set a block as non-cacheable. But as D8 development progressed that notion went away. Now you can make modules with awesome cache tagging and invalidation. But what you can't do is include PHP code in content using the infamous PHP filter and then have it execute on every page load. Caching won't run the code a second time the user loads your page.

Some of us immediate go to the drupal_flush_all_caches() command and try to dump cache at the end of the content render. But that doesn't work, because the command itself gets cached and doesn't run anymore. One might be tempted to try some elaborate scheme to fool Drupal into bouncing off of another redirect that flushes the cache, or setting up a flush on a cron cycle, etc. None of this will work.

So, resigning ourselves to the fact that we have to either do "proper" development and embrace the caching system, or disable caching altogether, we find a multitude of blog articles that talk about disabling caching in our development environments only, by copying the sites/example.settings.local.php to sites/default/settings.local.php and then uncommenting a bunch of stuff across three different files, including some YAML files and a a Twig config file. Yuck!

And, when that is all done, what then? We'll have a development environment that runs our PHP code, but a production site that does not. Why bother?

Well, my friends, Drupal 8 caching has yet-another learning curve for us, so here's the yucky pill we all have to swallow: you're not supposed to do what I'm about to tell you how to do. Drupal 8 caching makes sites run fast, and turning off caching makes your site run slow. Period.

"But..."

If you are committed to putting a print date("H:i:s"); command in a block and expect the time to update on every page load without writing a module, here's the quickest way to do it:

Forget about creating all the copy-paste versions of settings files and uncommenting various lines in various places. Just open your plain-old settings.php file, the one sitting in /sites/default (don't forget to unset the file permissions from 404 to 777 so you can edit it, and set it back immediately when you are done). Go to the end of that file, and add the following five lines:

// Todd told me to do this.  It's a terrible idea, but it works.
// For more info visit AllAboutTodd.com/story/d8-php-cache-troubles
 
$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/development.services.yml';
$settings['cache']['bins']['render'] = 'cache.backend.null';
$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.null';

These changes will be universal across your Drupal site and in all environments, etc. And it's only three lines of code, kept in one place. When that file is updated, clear your cache and enjoy your slightly slower, but always-executing embedded PHP code!!!

Tags: