Bootstrap Process
Blog

How Drupal handles the page request: Bootstrap Process

This is an interesting topic to get to know more about Drupal core activity. We will be looking into ‘how to use drupal echo on request?’ and ‘how many process it has gone through?’ Basically the process flow of Drupal Pipeline to interpret the steps & finally respond to the end users. Which is called as Bootstrap Process.

Having a little bit of knowledge on bootstrap could help us to develop & customized complicated area of drupal development.

Sample:
When we hit URL in browser: domain-name/node/234. which is a standard node page created under any of the Bundle.

Page request

The server responds on the browser request with the output and the same is rendered in the browser.

Page response

 

Technically, when a server receives a URL request, for eg: domain-name/article/lorem-ipsum,  drupal instantly takes care of the internal path & separates it from the domain name. Sometimes you will find a url with texts that do not really explain the content of the page for Eg: domain-name/?q=node/234. By enabling “Clean URLs” it help us to give a better suited url and make the it relevant and clean.

In Drupal each page request goes through index.php. You will find the index.php file in the Root directory of drupal.
So before we get started with the actual topic which is bootstrap process, i would like you to explore index.php. 
What does it contain?
Basically it has 4 lines of code that get called on each page request.

1. define('DRUPAL_ROOT', getcwd());
2. require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
3. drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
4. menu_execute_active_handler();
 
define('DRUPAL_ROOT', getcwd());

The first line defines a constant, DRUPAL_ROOT, containing the file path to the Drupal installation.

require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
The second line used is a constant, to load bootstrap.inc in the includes/subdirectory.bootstrap.inc and contains PHP code. Drupal uses the *.inc extension to prevent files from being executed directly. This way, not everyone can plug in example-name/includes/bootstrap.inc and get back a valid page.

drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
The third line of code, drupal_bootstrap() does the initialization. It basically checks for a connection to the database, loads modules, loads needed data into memory, and prepares everything for the final line of code in index.php.

menu_execute_active_handler();
The fourth line of code has menu_execute_active_handler() function, which handles the page request. This is the part that takes the ?q= half of the URL and produces a web page for the end users.

Get Started
Bootstrap process has total of 8 phases which initialize the database, set sessions, load libraries and so on.

DRUPAL_BOOTSTRAP_CONFIGURATION:  This setups configurations, sets error and handles exception. This function is called upon when Drupal encounters a PHP error or exception. attempting to log any errors or exceptions that may occur, and then throw a 500 Service unavailable response. In this process, error handling code is prepared, php settings are modified, settings.php gets loaded and some key global variables that Drupal uses throughout are initialized.

set_error_handler('_drupal_error_handler');
set_exception_handler('_drupal_exception_handler');

drupal_settings_initialize();
drupal_environment_initialize()

DRUPAL_BOOTSTRAP_PAGE_CACHE: It is used to serve the page from the cache. It checks if the requested IP is blocked or not, if it is blocked then it returns a  ‘403 Forbidden’ response. This depends on whether a user is logged in or not and if caching is enabled to decide whether to try to serve the page from cache (or at all).
If page caching is enabled, and the request is asking for a cached page, it returns the page.

drupal_block_denied(ip_address());
$user = drupal_anonymous_user();
$cache = drupal_page_get_cache();

 

DRUPAL_BOOTSTRAP_DATABASE: This Initializes the database connection and redirects to install.php if no $databases array has been defined in settings.php yet. If the call is from testing system (in which case it uses a separate set of tables) it loads database.inc, and more.

If we don't have anything in $GLOBALS ['databases'] and we haven't already started the installation process, then we get booted to /install.php since Drupal is assuming we need to install the site.
It registers the autoload functions for classes and interfaces

drupal_autoload_class()
drupal_autoload_interface() 

DRUPAL_BOOTSTRAP_VARIABLES: This loads variables from the variables table.
It will load all the variables from the database variables table and then overwrite the ones that were defined in settings.php. module.inc and any .module files that are required during the bootstrap phase will be loaded.

few important details:

It tries to load variable from the cache first, by looking for the variables cache ID in the cache_bootstrap table. If cache has failed, it tries to acquire a lock to avoid a stampede if a ton of requests are all trying to grab the variables table at the same time. Once it has the lock acquired, it grabs everything from the variables table and then it finally releases the lock.

DRUPAL_BOOTSTRAP_SESSION: This Initializes the user's session and
load the user's session from the DB. If the request isn't from a logged in user, it returns an anonymous user.

Drupal registers custom session handlers with PHP:

session_set_save_handler() PHP function allows us to set your own custom session storage functions, As you can see above, Drupal implements its own handlers for all 6 of those.

drupal_session_initialize()

Drupal has 6 session handler:

_drupal_session_open() and _drupal_session_close() Used for opening & closing the connection. both return TRUE;.

_drupal_session_read(): Fetches the session from the sessions table.

_drupal_session_write(): Checks if the session has been updated in the current page request page.

_drupal_session_destroy(): Deletes the appropriate row from the sessions DB table and sets the global $user object to be the anonymous user, and deletes cookies.

_drupal_session_garbage_collection(): Deletes all sessions from the sessions table that are older than whatever the max lifetime is set to in PHP.
 

DRUPAL_BOOTSTRAP_PAGE_HEADER: It sets HTTP headers to prepare for a page response.
This is probably the simplest of the bootstrap levels. It does 2 very simple things in the _drupal_bootstrap_page_header() function.

bootstrap_invoke_all('boot');
for uncached pages, this is where it happens.

Sends initial HTTP headers
It will sends a couple default headers (Expires and Cache-Control). anything can be called with drupal_add_http_header().


DRUPAL_BOOTSTRAP_LANGUAGE: It initializes the language types for multilingual sites.
This function is called only if we're talking about a multilingual site. It checks drupal_multilingual() which returns TRUE if the list of languages is greater than 1, and false otherwise. If it's not a multilingual site, it escapes.

DRUPAL_BOOTSTRAP_FULL: This includes a group of other files and executes a few other miscellaneous setups. The phase name is better thought as "Last", rather than "full". It loads all enabled modules and invokes hook_init().

So now that we already have the database, variable, session and configuration, we can add other miscellaneous .

All those things that we didn't need yet but may be reuired after this, we require here. ajax.inc, or mail.inc, or token.inc, image.inc, file.inc.

Load all enabled modules
The module_load_all() grabs the name of every enabled module using module_list() and then runs drupal_load() to load it.

Conclusion:

Bootstrapping is a self starting process that proceeds without an external input. It is the process of loading basic required software into the memory which will take care of loading other processes if needed.

There is lot of information and practice required. My intention was to provide a fair knowledge on the process. This is a good time to stop for now since each phase in the bootstrap process requires more in depth knowledge & information. Each phase of the bootstrap process contains a lot of code. While I could write an article in summarized way, there is a lot more to cover.

In a short note, How drupal deals with page request ? Drupal bootstraps on every request by going through different phases. These phases defined in bootstrap.inc

To summarize the steps:

When end user request for page.

What Drupal does:

  1. Separates the internal path from the full URL.
  2. Bootstraps and initialize the database, sessions etc
  3. Maps the path to a callback function.
  4. Modules can hook into the process and extend functionality and alter the content.
  5. The Theme System generates the HTML and styles it.
  6. Drupal returns a fully formed HTML page to the browser
  7. The browser renders the HTML page for the user