The Drupal core doesn’t attempt to do the processing for each of these steps. Instead,
after each step, it offers one or more modules the opportunity to handle that step. Put in
Drupal parlance, it offers opportunities for modules to hook into the lifecycle.
For example, we noted that Drupal checks to see if any module needs to be
initialized. What it actually does, is look to see if any modules implement a hook for
initialization. How does it do this? It scans the loaded modules to see if any of them
implement the function
hook_init(). To implement a hook in Drupal is to declare a
function that follows the hook naming pattern. For a fictional module named
hello to implement hook_init(), it would merely need to declare a function named
hello_init() (replacing the word hook with the name of the module).
Through this hook_init() hook, Drupal provides modules the ability to initialize
themselves or their own resources right at the beginning of the request. Once
all of these modules have been initialized, Drupal moves on to the next step. As
it progresses through the request, it calls hook after hook, giving modules the
opportunity to do their thing. Finally, it makes one last call for modules that
hook_exit(), and then it returns any remaining data to the client
and terminates the request.
Drupal’s hook system is perhaps the single most important aspect of Drupal
programming. Most (if not all) modules are nothing more than a collection of hook
implementations that Drupal automatically calls as it works its way through the
request lifecycle. It’s not just the Drupal core that declares and calls hooks. Any module
can declare and call its own hook. Many modules do in fact declare their own hooks,
offering other modules the opportunity to integrate deeply with their services.