Die aufrufende Funktion hook_menu()
ist menu_router_build () , die von menu_rebuild () aufgerufen wird . Es enthält den folgenden Code.
foreach (module_implements('menu') as $module) {
$router_items = call_user_func($module . '_menu');
if (isset($router_items) && is_array($router_items)) {
foreach (array_keys($router_items) as $path) {
$router_items[$path]['module'] = $module;
}
$callbacks = array_merge($callbacks, $router_items);
}
}
// Alter the menu as defined in modules, keys are like user/%user.
drupal_alter('menu', $callbacks);
Wenn zwei Module dieselbe Route definieren, module_implements()
überschreibt das letzte Modul in dem von zurückgegebenen Array den von den anderen Modulen definierten Wert.
Der zweite erforderliche Parameter module_implements()
ist wie folgt definiert:
$sort
Standardmäßig werden die Module nach Gewicht und Dateiname sortiert. Die Einstellungen für diese Option werden in der Modulliste nach TRUE
Modulnamen sortiert.
Da menu_router_build()
der zweite Parameter nicht an übergeben wird menu_implements()
, verwendet die Funktion den Standardwert für diesen Parameter. Dies bedeutet, dass die Liste der Module nach Gewicht und Dateiname sortiert ist. Wenn zwei Module das gleiche Gewicht haben, wird in der Liste als erstes Modul das Modul angezeigt, das alphabetisch an erster Stelle steht.
Darüber hinaus kann jede hook_module_implements_alter()
Modulimplementierung die Reihenfolge ändern, in der die Hooks aufgerufen werden.
Aus diesem Grund sollten Sie nicht davon ausgehen, dass Sie wissen, in welcher Reihenfolge die Hooks aufgerufen werden.
Wenn der Zweck des Codes darin besteht, die von einem anderen Modul implementierte Route zu ändern, z. B. weil eine Route entfernt werden soll, wenn ein zweites Modul installiert und aktiviert wird, sollte der Code verwendet werden hook_menu_alter()
. Wenn Sie versuchen zu verstehen, welches Modul bei Routenkonflikten "gewinnen" würde, würde ich einen solchen Routenkonflikt lieber vermeiden und eine Route definieren, die noch nicht von einem anderen Modul definiert wurde.
Wenn Sie dann implementieren hook_menu_alter()
und sicherstellen möchten, dass Ihr Modul zuletzt ausgeführt wird, sollten Sie auch implementieren , um das Modul zu sein, das eine Route effektiv überschreibt hook_module_implements_alter()
.
function mymodule_module_implements_alter(&$implementations, $hook) {
if ($hook == 'menu_alter') {
// Move mymodule_menu_alter() 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['mymodule'];
unset($implementations['mymodule']);
$implementations['mymodule'] = $group;
}
}