Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
By ParisLiakos on
Change record status:
Published (View all published change records)
Project:
Introduced in branch:
8.x
Issue links:
Description:
In Drupal 7 hook_boot() was being fired on the beginning of all page requests, providing modules the ability to run code on cached pages.
In Drupal 8 hook_boot() was removed since the same results can be achieved with other ways, for example:
- A module that needs to interrupt the request very early based on certain conditions can use an event listener (see #1794754: Convert ban_boot() to an event listener) (Note that modules are loaded by this stage unlike in Drupal 7.)
- A module that needs to run on cached pages should prompt its users to add code in settings.php
Drupal 7
/**
* Implementation of hook_boot(). Runs even for cached pages.
*/
function mymodule_boot() {
// @todo remove this debug code
drupal_set_message('mymodule_boot executed');
}
Drupal 8:
# file should be in /mymodule/mymodule.services.yml
services:
mymodule.mymodule_subscriber:
class: Drupal\mymodule\MyModuleSubscriber
tags:
- { name: 'event_subscriber' }
// file shoud be in /mymodule/src/MyModuleSubscriber.php
/**
* @file
* Contains \Drupal\mymodule\MyModuleSubscriber.
*/
namespace Drupal\mymodule;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Provides a MyModuleSubscriber.
*/
class MyModuleSubscriber implements EventSubscriberInterface {
/**
* // only if KernelEvents::REQUEST !!!
* @see Symfony\Component\HttpKernel\KernelEvents for details
*
* @param Symfony\Component\HttpKernel\Event\GetResponseEvent $event
* The Event to process.
*/
public function MyModuleLoad(GetResponseEvent $event) {
// @todo remove this debug code
drupal_set_message('MyModule: subscribed');
}
/**
* {@inheritdoc}
*/
static function getSubscribedEvents() {
$events[KernelEvents::REQUEST][] = array('MyModuleLoad', 20);
return $events;
}
}
Impacts:
Module developers
Comments
Does this even work?
Does this even work? Define class = magic?
I can't seem to get Drupal to recognize my Bundle class extension just by creating a class in myModule/lib/Drupal/myModule/myModuleBundle.php. Uninstalled, enabled, refreshed cache, added exit calls in the build method, etc... Nothing.
Edit: Yes, this does nothing. It is broken.
Might be ok
Okay, yeah, this documentation is bad, but there is a different way now.
The first class is not needed and the event subscriber should be defined in "mymodule.services.yml".
You can use StackMiddleware plugin
I used StackMiddleware plugin instead of hook_boot():
mymodule/mymodule.services.yml
mymodule/src/StackMiddleware/MyModule.php
You also can see an example of StackMiddleware plugin in Page Cache module:
/core/modules/page_cache/src/StackMiddleware/PageCache.php
/core/modules/page_cache/page_cache.servcies.yml
https://api.drupal.org/api/drupal/core%21modules%21page_cache%21src%21St...
Is this still valid, with
Is this still valid, with Drupal 8/9? And if so, please explain how handle() returns whatever the custom code needs returned. It seems to be returning something without any nexus to the whatever the custom code is doing.
I'm not sure it's working now
I'm not sure it's working now, it was 5 years ago. You'd better use priority 300 to avoid cache.
But if you want example, I used this code for this module:
https://www.drupal.org/project/cleanpager/releases/8.x-1.x-dev
It still works
I confirm that the middleware approach still works (and not the event subscriber one, which will never be hit before page cache is generated).
The only thing to do on Drupal 10 is to raise the priority of it to above 200 (as it's the weight of page_cache http_middleware). I'm using 210 and managed to invalidate a block cache on each request.
Setting the priority greater
Setting the priority greater than 200 also let me skip caching and replicate the functionality of hook_boot, without needing StackMiddleware.
Apparently the page cache injects itself at priority 200, so a higher priority will beat the cache.
User module priority
The user module operates at priority 300, so if your subscriber requires interaction with loaded user entities and core user functions like
\Drupal::currentUser()
, then your subscriber should be operating less than 300.User Module:
$events[KernelEvents::TERMINATE][] = ['onKernelTerminate', 300];
In creating the Simple Access Log module I set my priority to 250 so it would operate with information about users but before the Dynamic Page Cache.
I cannot confirm this. Using
I cannot confirm this. Using 250 or 300 my code does not get triggered on cached pages. Also cannot use the Middleware approach in my case because I want to check if the user is authenticated which does not work there. Any idea how to do this?