Problem/Motivation

The drupal_classloader() function was introduced into core but was added towards the end of the first bootstrap phase (bootstrap configuration). There is actually quite a bit of code that executes before the class autoloader is available that could very well make use of autoloading capability. (e.g. initializing the request object or other code that could be used in the earliest parts of the bootstrap process).

At first it seemed it might be enough to call drupal_classloader at the beginning bootstrap configuration, but in some cases (e.g. during install) autoloading capabilities may be required even BEFORE configuration is bootstrapped.

Proposed resolution

Add a new bootstrap phase dedicated to loading the autoloader and registering namespaces of classes required in the early bootstrap. This phase would run before anything else.

Remaining tasks

None.

User interface changes

None.

API changes

No API's touched or created.

Original report by me (andremolnar)

Comments

andremolnar’s picture

StatusFileSize
new4.13 KB

This patch is a follow up to the code review by @Rob Loach in #1290658-110: Move all module-provided classes to PHP namespaces (PSR-0 or similar), and autoload them without the registry [policy, no patch]
(edit - accidentally re-uploaded last patch from the old issue under a new name in comment #1 - deleted comment - this now the correct patch)

andremolnar’s picture

Status: Active » Needs review
robloach’s picture

Status: Needs review » Reviewed & tested by the community

Having the autoloader earlier in the bootstrap means we can move some of the bootstrap to PSR-0 classes in follow up patches. Patch applies cleanly, code looks good, tests pass.

lars toomre’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/includes/bootstrap.incundefined
@@ -2284,22 +2294,12 @@ function _drupal_exception_handler($exception) {
 /**
- * Sets up the script environment and loads settings.php.
+ * Initialize the class autoloader and register core namespaces required for
+ * early bootstrap.

The docblock for this new function needs some work.

The first line should start with an active verb and it should be no more than 80 characters.

You might want to add a second explanation line (after an intervening space) that expands on what this phase of bootstrap does.

andremolnar’s picture

Status: Needs work » Needs review
StatusFileSize
new4.22 KB

Updated based on comments in #5

sun’s picture

Status: Needs review » Needs work
+++ b/core/includes/bootstrap.inc
@@ -2147,6 +2152,7 @@ function drupal_anonymous_user() {
+    DRUPAL_BOOTSTRAP_AUTOLOADER,
     DRUPAL_BOOTSTRAP_CONFIGURATION,
     DRUPAL_BOOTSTRAP_PAGE_CACHE,
     DRUPAL_BOOTSTRAP_DATABASE,

The new phase name "autoloadER" doesn't seem to be in line with the other phase names.

What about DRUPAL_BOOTSTRAP_AUTOLOAD ?

+++ b/core/includes/bootstrap.inc
@@ -2284,22 +2294,14 @@ function _drupal_exception_handler($exception) {
+ * Initializes the class autoloader.
+ *
+ * Makes class autoloader available to all subsequent bootstrap phases.
+ * Registers both the Symfony and Drupal namespaces with the autoloader.

This additional description doesn't provide any further information - except for explicitly mentioning Symfony and Drupal namespaces, but that's rather a code/implementation detail.

I'd recommend to drop the description and just keep the summary:

Initializes the class autoloader and registers namespaces.

+++ b/core/includes/bootstrap.inc
@@ -2284,22 +2294,14 @@ function _drupal_exception_handler($exception) {
-

The blank line here would be nice to keep for readability.

robloach’s picture

Status: Needs work » Needs review
StatusFileSize
new4.39 KB

Updated with comments in #7. Replaced the description to point over to drupal_classloader() and uses "autoload" for the const and bootstrap function name.

lars toomre’s picture

This patch now looks good to me. I will leave to others for RTBC.

andremolnar’s picture

StatusFileSize
new4.4 KB

Actually 'autoloader' is the Noun. We are boostrapping the autoloader - not the 'autoload'.

Otherwise all other code comments and whitespace changes look good.

robloach’s picture

Status: Needs review » Reviewed & tested by the community

Agreed. The "autoloader" is what we're bootstrapping, just like how we're bootstrapping the "configuration".

catch’s picture

Component: wscci » base system

Fixing component.

catch’s picture

Status: Reviewed & tested by the community » Needs work
 /**
+ * Sets up the script environment and loads settings.php.
+ */
+function _drupal_bootstrap_configuration() {
+  // Set the Drupal custom error handler.
+  set_error_handler('_drupal_error_handler');
+  set_exception_handler('_drupal_exception_handler');
+
+  drupal_environment_initialize();
+  // Start a page timer:
+  timer_start('page');
+  // Initialize the conf

Two things:

- Why do these belong in _drupal_bootstrap_configuration() more than _drupal_bootstrap_autoload(), I'm assuming they were put here simply because it was the first step, now it's not. Seems like a good chance to tidy up.

- more importantly. drupal_classloader() calls variable_get(), variable_get() depends on $conf, which can be altered by settings.php, so the patch is broken as it currently stands.

Crell’s picture

I suggest we just rip out the APC option for the autoloader for the moment. We know that other changes are coming in this area. We can revisit that later when we're done breaking stuff.

As for the error handlers, I disagree. Those don't belong in autoload. If anything they'd be part of an "environment init" bootstrap phase, but really, we need to stop thinking in terms of "environment creation". (Arguably those functions could be moved to a class, then autoload that! :-) ). We don't need those for the class loader, I think, so let's punt on that for now as well.

sun’s picture

That assumes there cannot be any errors in the autoloader code, which sounds bogus.

Crell’s picture

No, it assumes that any errors there can be handled by the default PHP error handling, because they're sufficiently rare.

andremolnar’s picture

Re: #13

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

These lines in the patch are simply artifacts of the way the diff came out. That code is already committed in _drupal_bootstrap_configuration - can the virtue of those functions and their dependency on $conf be moved to its own issue?
On a more looking-towards-the-future level error.inc could be re-written to be a class that is autoloaded. We'll need an autoloader ready before we can do that.

The purpose of this patch is to get autoloading available ASAP in bootstrap since it already poses a development obstacle that is sure to come up more in the near future. Can the patch be considered on that basis alone?

Crell’s picture

andre: Those functions do not depend on $conf. The variable_get() call in the class loader setup depends on $conf. That's what I suggest we just remove and come back to later.

andremolnar’s picture

Status: Needs work » Needs review
StatusFileSize
new4.4 KB

Of course. My mistake.

Here's an updated patch to remove the offending APC code committed in #1290658-97: Move all module-provided classes to PHP namespaces (PSR-0 or similar), and autoload them without the registry [policy, no patch]. I left the code comment as a @TODO (maybe to be followed up in the other issue?!)

andremolnar’s picture

StatusFileSize
new5.96 KB

Gah, must remember to commit before git diff 8.x..foobranch > patch
Corrected patch attached.

Status: Needs review » Needs work

The last submitted patch, drupal_classloader-1451524-19.patch, failed testing.

robloach’s picture

Might be easier to get #1424924: Use Composer for updating Symfony components (without removing Symfony code from repo) in first, because then we could simply just call drupal_classloader() during the bootstrap. Saves us a function definition.

robloach’s picture

Issue summary: View changes

Updating links to use markdown for readability

sun’s picture

Issue summary: View changes
Status: Needs work » Closed (won't fix)

Unless I'm terribly mistaken, this issue is obsolete by now?

We're using the Composer ClassLoader in the meantime, which is manually included by all front-controllers before drupal_bootstrap() is called.

sylvain lecoy’s picture

Unless the composer classloader does not loads modules custom classes, this issue is still not fixed, otherwise yes..!