Hi,
coming over from #1693466-8: Duplicate module?

Let's just make sure that the two modules don't get in the way of each other. Especially, if you have modules A and B installed, where A requires classloader, and B requires xautoload.

We want that both can be installed, but only one of them should be active at a time.

I think, at first we should agree which of the two modules will be deactivated, if both are installed.
xautoload is designed to be a full replacement of classloader. The other direction is not the case. So, I would suggest that classloader is the one to be deactivated. I hope you can live with that!

I am happy to implement a switch logic in xautoload, if classloader gets a killswitch.. would that be ok with you?
(maybe the killswitch does already exist, didn't check)

Now, I think it is more tricky than that.
Some modules might call drupal_classloader() or drupal_classloader_register() directly. If we simply deactivate classloader, then the namespaces registered this way will be lost.

So, if we deactivate classloader, then we need to pass along any namespace registration to xautoload.

-----------

So, what I would propose:
- I develop a registration layer in xautoload, that is compatible with symfony class loader. (*)
Then if both modules are enabled,
- drupal_classloader() can return the xautoload version.
- classloader_boot() and classloader_init() do nothing.

Does this sound ok?

------------

(*) I still need to think about if 100% compatiblity will be possible.
The addPrefix, addPrefixes, findFile() should work fine.
getPrefixes() and getFallbackDirs() is more tricky, because xautoload stores those things in a different way (for easier lookup). Maybe it could still be simulated.
register(), unregister() and loadClass() are tricky, because the ClassFinder is not the thing that actually does the autoloading. On the other hand, a compatibility wrapper could have access to everything.

Comments

sun’s picture

Status: Active » Postponed (maintainer needs more info)

Why do we need to do anything in the first place?

This is about auto-loading PHP classes. classloader will load PSR-0 classes. PHP allows to register multiple, alternative class loaders. If the PSR-0 class loader does not find a class, then the next loader is asked.

donquixote’s picture

Performance.
The fewer redundant lookups we have, and the fewer redundant initialization, the better.

Esp, one of the goals of xautoload is to avoid the loop over all registered namespaces on every lookup.
If there is another autoloader in the game which runs before, this becomes quite pointless.

Also, predictability:
If two autoloaders are registered for the same purpose, and something does not work, then people will have a hard time to figure out which one's fault it is.

-----------

I want to do some benchmarking anyway. Your module being out is actually quite helpful for that :)
If you want, we could wait for the result of the benchmarks, and then I propose a patch.

Or, we could wait until you have the composer stuff implemented. I did not study the composer class loader in detail yet, maybe this introduces some new arguments into the equation.

sun’s picture

The code of classloader is feature-complete and not supposed to change at this point.

(That is, of course, unless there's a critical bug in the backport.)

And to clarify further: The composer directory structure is also backported 1:1 from D8. (Tough looks like I forgot to commit the composer.json/composer.lock files.) In any case, that will only become relevant in case the Symfony classloader needs to be updated for some reason (which again, would require a critical bug or security issue in the upstream Symfony\ClassLoader component).

If you think that xautoload's class loader is faster for some reason, then register it first, using the $prepend argument.

@see http://php.net/manual/en/function.spl-autoload-register.php

donquixote’s picture

I made a sandbox module for benchmarks.
http://drupal.org/sandbox/donquixote/1762858

First test runs indicate:

  • xautoload did run 3x faster in my own test runs.
  • enabling or disabling classloader while xautoload was enabled did not make a difference in the test.
    However, a variation of the test with class_exists() on a non-existing classname shows a really bad performance if both are enabled.
  • Bootstrap time was not measured, even though it probably does have an impact.
  • I had difficulties analyzing the effect of APC cache on both modules. (both of them support it)

Conclusion for this issue:
For now we can live with the concept that both loaders will coexist. I don't care enough that I would spend time on it atm.
However, there is an argument for being able to mute classloader.

donquixote’s picture

Title: Let classloader and xautoload not get in each other's way. » classloader + xautoload: Avoid redundant operations

Changing issue title.
The "get in each others' way" is no longer an issue, or has never been.
Redundancy / performance is still a concern, and will become more relevant if more modules pick up PSR-0.