8.2.x module.api.php hook_module_implements_alter(&$implementations, $hook)
8.0.x module.api.php hook_module_implements_alter(&$implementations, $hook)
8.1.x module.api.php hook_module_implements_alter(&$implementations, $hook)
7.x system.api.php hook_module_implements_alter(&$implementations, $hook)

Alter the registry of modules implementing a hook.

This hook is invoked during module_implements(). A module may implement this hook in order to reorder the implementing modules, which are otherwise ordered by the module's system weight.

Note that hooks invoked using drupal_alter() can have multiple variations (such as hook_form_alter() and hook_form_FORM_ID_alter()). drupal_alter() will call all such variants defined by a single module in turn. For the purposes of hook_module_implements_alter(), these variants are treated as a single hook. Thus, to ensure that your implementation of hook_form_FORM_ID_alter() is called at the right time, you will have to change the order of hook_form_alter() implementation in hook_module_implements_alter().


$implementations: An array keyed by the module's name. The value of each item corresponds to a $group, which is usually FALSE, unless the implementation is in a file named $module.$group.inc.

$hook: The name of the module hook being implemented.

Related topics

3 functions implement hook_module_implements_alter()

Note: this list is generated by pattern matching, so it may include some functions that are not actually implementations of this hook.

common_test_module_implements_alter in modules/simpletest/tests/common_test.module
Implements hook_module_implements_alter().
module_test_module_implements_alter in modules/simpletest/tests/module_test.module
Implements hook_module_implements_alter()
system_test_module_implements_alter in modules/simpletest/tests/system_test.module
Implements hook_module_implements_alter().
3 invocations of hook_module_implements_alter()
drupal_alter in includes/module.inc
Passes alterable variables to specific hook_TYPE_alter() implementations.
ModuleImplementsAlterTestCase::testModuleImplementsAlter in modules/simpletest/tests/module.test
Tests hook_module_implements_alter() adding an implementation.
module_implements in includes/module.inc
Determines which modules are implementing a hook.


modules/system/system.api.php, line 2022
Hooks provided by Drupal core and the System module.


function hook_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'rdf_mapping') {
    // Move my_module_rdf_mapping() to the end of the list. module_implements()
    // iterates through $implementations with a foreach loop which PHP iterates
    // in the order that the items were added, so to move an item to the end of
    // the array, we remove it and then add it.
    $group = $implementations['my_module'];
    $implementations['my_module'] = $group;


This seems to be substantially non-functional...

It looks like it's called early in the request, for hooks like hook_boot, before most modules have been loaded. The list of modules implementing this hook is cached at that time and not re-calculated once all modules are loaded.

This means that the hook works only for very core modules, such as entity, plus under various unusual circumstances such as "drush cc all". It doesn't work for ordinary modules serving normal requests.

The reason it may seem like this hook is not invoked is because each hook is added to the registry only when needed. After a cache clear, only basic core hooks are needed to generate the page. However this hook is called everytime any new hook is called for the first time after a cache clear. Then you have an opportunity to rearrange the hook order or even remove implementations. The modifications will be saved into the cache.

hook_module_implements_alter() seems to be not usable in any module that isn't a bootstrap module, because the list of implementations is cached very early. If you put a hook_boot in your module and then clear cache a lot and esnure that the list of bootstrap modules is properly regenerated, that seems to make this hook fire.

Addendum: This is only true if you have another module that uses hook_boot that calls module_implements. However, at least one authentication system module does this. Others might as well.

There are two issues saying that calling module_implements() from within a hook_boot invocation is just plain disallowed / unsupported, and that this should be documented as such (or even an exception thrown if code does this, to prevent hard to trace bugs): 496170 and 1415278.

The first issue could probably benefit from the names of any modules that do this. I couldn't find this authentication system module.

Just to clarify.
Bootstrap module is a module that implements hook_boot(). This will set 'bootstrap' value to '1' in 'system' table in DB.

hook_module_implements_alter() is not called indeed if current module does not implement hook_boot().

The theme/template version of this hook can be found at hook_theme_registry_alter

The documentation above shows a way of making a module always execute it's hook last, but what about if you want a module to always execute first?

This is how I did it:

function my_module_module_implements_alter(&$implementations, $hook) {
  if ($hook != 'the_hook_to_change') {

  $module = 'my_module';
  $group = array($module => $implementations[$module]);
  $implementations = $group + $implementations;

This will make my_module's hook always run before any other module.

If you have a hook_form_FORM_ID_alter() in your module, and you want it to execute last...

function my_module_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'form_alter' && isset($implementations['my_module'])) {
    $group = $implementations['my_module'];
    $implementations['my_module'] = $group;

The module_implements_alter() will always be called with the base hook, even if you are implementing something different. The extra isset on the $implementations array is needed in case you don't actually implement hook_form_alter() as well.

I had to implement an empty hook_form_alter and have this in hook_module_implements_alter:

if ($hook == 'form_node_form_alter' || $hook == 'form_alter') {

bofore my hook_form_node_form_alter was moved to the end of the line.

That`s a great catch. Had the issue with this as well and seems that this approach is required for hook_form_FORM_ID_alter to work.
Actually had to add a check for the module name to prevent the undefined index notices:

if (($hook == 'form_FORM_ID_alter' || $hook == 'form_alter') && isset($implementations['module_name']) {

Thanks a lot man.
It saved a lot of headache for me.

Note that hook_url_inbound_alter() implementations are called in reverse order, see includes/path.inc:

  // Allow other modules to alter the inbound URL. We cannot use drupal_alter()
  // here because we need to run hook_url_inbound_alter() in the reverse order
  // of hook_url_outbound_alter().
  foreach (array_reverse(module_implements('url_inbound_alter')) as $module) {
    $function = $module . '_url_inbound_alter';
    $function($path, $original_path, $path_language);

Let's say you have a module that implements both hook_form_alter and hook_form_FORM_ID_alter, and in another module you want to remove the invocation of hook_form_FORM_ID_alter. You'd think you could implement hook_module_implements_alter() and remove it, but if you do you'll find that it is invoked anyway. This is because when an array of hooks is passed to module_invoke_all, if any one of the hooks is in the implementation list, they will all be called (if they exist), whether or not they were removed in a hook_module_implements_alter() implementation. See lines 1058 and following in module.inc. In my opinion this is a rather nasty and subtle bug, but I don't think it is likely to be addressed in D7. I have not checked if this is the case in D8.

If Module B has a weight higher (or is later in the alphabet) than Module A and both do module_implements_alter on the same hook to go first, Module B will end up getting called before Module A.

 * Implements hook_module_implements_alter().
function og_test_module_implements_alter(&$implementations, $hook) {
  if ($hook != 'entity_delete') {

  // Switch the orders of the implementations.
  $og = $implementations['og'];
  $og_test = $implementations['og_test'];

  unset($implementations['og'], $implementations['og_test']);

  $implementations['og_test'] = $og_test;
  $implementations['og'] = $og;