If we call drupal_bootstrap() with $new_phase = FALSE, it will not perform phases which are higher than initially requested phase.

Example:

Step 1. We call drupal_bootstrap(DRUPAL_BOOTSTRAP_PAGE_CACHE). We expect that Drupal will return cached page (if configured and cached version is available).

Step 2. drupal_bootstrap() calls _drupal_bootstrap_page_cache(), which (if there are no cache settings in settings.php) calls drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES, FALSE).

Step 3. drupal_bootstrap(), when called with $new_phase = FALSE, ignores all steps which are greater than $final_phase, but $final_phase is DRUPAL_BOOTSTRAP_PAGE_CACHE (and it changes only when $new_phase = TRUE.

if ($new_phase && $phase >= $stored_phase) {
    $final_phase = $phase;
}
...
while ($phases && $phase > $stored_phase && $final_phase > $stored_phase) {
...
}

Step 4. drupal_bootstrap() returns with DRUPAL_BOOTSTRAP_PAGE_CACHE result (instead of expected DRUPAL_BOOTSTRAP_VARIABLES).

Step 5. _drupal_bootstrap_page_cache() tries to read cache settings from db with $cache_enabled = variable_get('cache') and receives FALSE always, since variables have not been loaded.

Result: drupal_bootstrap(DRUPAL_BOOTSTRAP_PAGE_CACHE) never reads cache settings from db.

drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL) used in index.php works just because $final_phase == DRUPAL_BOOTSTRAP_FULL inside drupal_bootstrap() and any requested (with $new_phase = FALSE) phase is performed.

We could remove $new_phase argument and $final_phase variable from drupal_bootstrap() as it was suggested by @chx and @catch 10 years ago (see original issue summary).
I did not find any consequences of removing $new_phase argument.

Documentation should be changed to reflect the changes.

Perhaps, we should implement some testing for drupal_bootstrap() (but I am not sure we really need it).

Comments

catch’s picture

Status: Active » Needs review

Status: Needs review » Needs work

The last submitted patch failed testing.

asvira’s picture

Title: Remove $final_phase argument from drupal_bootstrap() » drupal_bootstrap() misses some phases in rare cases (Remove $new_phase argument and $final_phase variable from drupal_bootstrap())
Component: base system » bootstrap system
Priority: Normal » Major
Issue summary: View changes
Status: Needs work » Needs review
StatusFileSize
new2.37 KB
new2.76 KB

Seems that Drupal 7 has only 2 occurrences of calling drupal_bootstrap() with 2 arguments.

Contributed and custom modules may update their code to meet new definition of drupal_bootstrap(), but use of old definitions does not break anything.

After some thoughts, I removed $current_phase since it is used just to extract phase from $phases and to move it to $stored_phase (the condition if ($current_phase > $stored_phase) is always TRUE since $current_phase has just been extracted from $phases and $stored_phase contains previous phase). Recursion does not make any difference, since $phases and $stored_phase are static.

Status: Needs review » Closed (outdated)

Automatically closed because Drupal 7 security and bugfix support has ended as of 5 January 2025. If the issue verifiably applies to later versions, please reopen with details and update the version.