Drupal 7 Line by Line Part 3 - DRUPAL_BOOTSTRAP_CONFIGURATION

In this third part of the Line by Line series I'll take a look at the first phase of the bootstrap process: namely DRUPAL_BOOTSTRAP_CONFIGURATION.

In the first part of this series I looked at index.php. In the second part I continued through the workings of the drupal_bootstrap function.

Up until now I've been literally going through the code line by line. From this point on I'm going to be less literal and only occasionally do line by line analysis where I think a closer look might be interesting.

So lets jump back in where we left off. I'd just finished explaining that Drupal was aware that it needed to do a full bootstrap and it was just about to start the first phase of that process.

Drupal calls the function _drupal_bootstrap_configuration().

Error Handling

The very first thing that happens in the first phase of the bootstrap process is Drupal defines its own error handling functions. Up until this point if an error had occurred in the code php would have used its own error handling to report the problem. Luckily very few lines of code have been executed to this point.

Drupal sets an error handler as well as an exception handler. The exception handler is new to Drupal since Drupal 7 now includes object oriented code which when called could generate exceptions.

What happens inside of these error handling functions is best left to its own discussion. Just be aware that they exist and they are defined very early on. Also note the error handling code found in the error.inc file isn't loaded until the first error occurs. Our first encounter of lazy loading in Drupal 7.

drupal_environment_initialize().

<?php /**
* Initialize PHP environment.
*/
function drupal_environment_initialize() {?>

In this function Drupal first cleans up parts of the $_SERVER super global. It makes sure that there is a valid server protocol variable set. It also does a security check on the http host variable.

<?php
 
// When clean URLs are enabled, emulate ?q=foo/bar using REQUEST_URI. It is
  // not possible to append the query string using mod_rewrite without the B
  // flag (this was added in Apache 2.2.8), because mod_rewrite unescapes the
  // path before passing it on to PHP. This is a problem when the path contains
  // e.g. "&" or "%" that have special meanings in URLs and must be encoded.
 
$_GET['q'] = request_path();
?>

The request_path() function cleans up the default $_GET['q'] value as per the code comments above.1

The rest of drupal_environment_inistialize is literally self explanatory.

<?php
 
// Enforce E_ALL, but allow users to set levels not part of E_ALL.
 
error_reporting(E_ALL | error_reporting());

 

// Override PHP settings required for Drupal to work properly.
  // sites/default/default.settings.php contains more runtime settings.
  // The .htaccess file contains settings that cannot be changed at runtime.

  // Don't escape quotes when reading files from the database, disk, etc.
 

ini_set('magic_quotes_runtime', '0');
 
// Use session cookies, not transparent sessions that puts the session id in
  // the query string.
 
ini_set('session.use_cookies', '1');
 
ini_set('session.use_only_cookies', '1');
 
ini_set('session.use_trans_sid', '0');
 
// Don't send HTTP headers using PHP's session handler.
 
ini_set('session.cache_limiter', 'none');
 
// Use httponly session cookies.
 
ini_set('session.cookie_httponly', '1');

 

// Set sane locale settings, to ensure consistent string, dates, times and
  // numbers handling.
 
setlocale(LC_ALL, 'C');
?>

With drupal_environment_initialize() complete jump back to _drupal_bootstrap_configuration().

Its at this stage that Drupal, completely out of the blue, decides to start a timer function (to keep tack of page execution time). This is rather unexpected since you might not have known that Drupal has timer functions at all - let alone ones that are called on every single page load. Just something to keep in mind when developing your next killer module - you have access to timer_start, timer_read, and timer_stop functions.

drupal_settings_initialize();

Finally _drupal_bootstrap_configuration calls drupal_settings_initialize().

<?php/**
* Loads the configuration and sets the base URL, cookie domain, and
* session name correctly.
*/
function drupal_settings_initialize() {
  global
$base_url, $base_path, $base_root;

 

// Export the following settings.php variables to the global namespace
 
global $databases, $cookie_domain, $conf, $installed_profile, $update_free_access, $db_url, $db_prefix, $drupal_hash_salt, $is_https, $base_secure_url, $base_insecure_url;
?>

It starts off by defining a long list of global variables that get used throughout Drupal.

Drupal then looks for and includes the settings.php file. This file is often found in /sites/default/settings.php, but if you have a multi-site install of Drupal it could be in different directories under /sites/ depending on which site you are currently looking at. Drupal figures out which directory settings.php is in with a call to conf_path().

I won't go through conf_path() line by line, but it is worth reading the documentation for that function if you ever wondered how Drupal just knew where to load settings from2.

An entire post could be dedicated to settings.php, but what you need to know here is that your site's configuration is loaded in the first bootstrap phase. It is very much worthwhile to read the code comments in settings.php.

In the rest of the function, variables for base URL, cookie domain, and session name are all set correctly.

And with that, the first phase bootstrap phase is complete.

Summary

The first bootstrap phase is all about laying the foundation for the rest of page execution. Custom error handling code is prepared, php settings are modified, settings.php gets loaded and some key variables used later on are initialized.

Next time I'll look at phase 2 of the Drupal bootstrap process.

Footnotes

When you have clean urls enabled, you are hiding 'ugly' urls from your site's visitors. The ugly url is in the form http://example.com/index.php?q=foo/bar/baz. Its easy to forget that Drupal paths are really a single parameter passed via HTTP GET.

The code is fun with gems like: $server = explode('.', implode('.', array_reverse(explode(':', rtrim($_SERVER['HTTP_HOST'], '.')))));
. It just gives you the feeling that there has got to be a better way to accomplish the same thing - but that voodoo gets the job done.

January 5th 2011 9AM
By: andre

 

Comments

Still following, and loving it :)

Small tyops :

  • at the very beginning (2nd sentence), you forgot the link to the second part
  • in the summary at the end, I think you meant "rest", not "reset"

Thanks to you I'm not afraid of reading this "scary" bootstrap.inc file ! I'm looking forward the rest of the series :)

Thanks

Thanks. Missing closing tag on the link and indeed a typo near the end.

All fixed now.
andre

Just discovering this series!

Great idea, Andre! I've made a feeble attempt at this type of comb-through in the past, but it was only because I was stuck on a wifi-less plane with only copies of Drupal and the ever-trusty Notebook++ on my netbook. It's been awhile, and since I'm just about to hop a plane back to TO in a few hours, maybe it's a good time to jump back in...

Thanks for the kick in the pants, and I'll definitely catch up on the series later :)