0

In Drupal 7 created a module which implemented hook_init().

I put an error log message as the first line of the function.

function my_module_init() {
  error_log('running init');
}

On each page load of the site I see the error message multiple times. I was expecting hook_init() to be ran exactly once per page load. Why is it running multiple times?

2
  • A similar issue was discussed in Alternatives to hook_init(). The comments and the accepted answer are highly recommended. Jul 12, 2012 at 19:22
  • In the other question, the fact hook_init() is invoked twice is just marginal. The main question is about alternatives to hook_init(), as the title says. In fact, the accepted answer offers an alternative implementation of hook_init(), alternative hooks to implement, and an explanation of why hook_init() is not invoked twice per page request; the latter part is marginal for that question, though.
    – apaderno
    Jul 12, 2012 at 19:47

2 Answers 2

6

hook_init() is invoked by Drupal only once for each requested page; it is the last step done in _drupal_bootstrap_full().

  // Drupal 6
  //
  // Let all modules take action before menu system handles the request
  // We do not want this while running update.php.
  if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') {
    module_invoke_all('init');
  }
  // Drupal 7
  //
  // Let all modules take action before the menu system handles the request.
  // We do not want this while running update.php.
  if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') {
    // Prior to invoking hook_init(), initialize the theme (potentially a custom
    // one for this page), so that:
    // - Modules with hook_init() implementations that call theme() or
//   theme_get_registry() don't initialize the incorrect theme.
    // - The theme can have hook_*_alter() implementations affect page building
//   (e.g., hook_form_alter(), hook_node_view_alter(), hook_page_alter()),
//   ahead of when rendering starts.
    menu_set_custom_theme();
    drupal_theme_initialize();
    module_invoke_all('init');
  }

If hook_init() is being executed more than once per each page request, there could be a module that calls module_invoke_all('init'). It could also happens that a module calls drupal_goto(), and redirects the user to another page; this would cause a new page request, and a new invocation of hook_init(), if the page is not served from the cache.

In Drupal 7, there is just a way to check if hook_init() is invoked twice per page request, and it is to implement hook_init() using the following code.

function mymodule_init() {
  watchdog('mymodule', 'Request time: !timestamp', array('!timestamp' => REQUEST_TIME), WATCHDOG_DEBUG);
}

As REQUEST_TIME is a constant that Drupal defines each times it bootstraps (which means each times a page is requested), if you see two consecutive watchdog() entries showing the same value, then hook_init() is being invoked twice, or it is invoked in two different page requests done in less than a second. If the difference is 2 seconds, for example, then hook_init() is invoked in two different page requests.

2

hook_init() runs once per page request on all non-cached pages.

Keep in mind that when you load a page in your browser, it loads the page and all assets on that page (CSS, JS, images, etc).

Also keep in mind that Drupal handles 404 errors by default1, so if there is a bad URL on the page (say /favicon.ico), then Drupal may handle that asset, depending on how you have Apache configured.

Image styles used on a page that don't have derivatives on the filesystem will also get handled by Drupal and go through the whole bootstrap process.

My advice is to try to match up the timestamps in the error log with the Apache access_log and see what is going on.

So, it is very likely that your multiple entries in the error log from hook_init() are from individual URLs that Drupal has handled in quick succession, but potentially from starting from a single browser page load.

1 This bahavior can be refined in more recent versions of Drupal 7.

2
  • You mentioned loading images. Would requesting images trigger hook_init()? I don't see why requesting an image would be considered as a page request.
    – rexposadas
    Jul 12, 2012 at 23:26
  • 1
    If they are defined as image styles, then the first load may trigger Drupal to render out the derivative.
    – mpdonadio
    Jul 12, 2012 at 23:53

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.