[wp-trac] [WordPress Trac] #36335: Next generation: core autoloader proposal
WordPress Trac
noreply at wordpress.org
Mon Jun 6 07:39:48 UTC 2016
#36335: Next generation: core autoloader proposal
-----------------------------+-----------------------------
Reporter: dnaber-de | Owner:
Type: feature request | Status: new
Priority: normal | Milestone: Future Release
Component: General | Version:
Severity: normal | Resolution:
Keywords: 2nd-opinion | Focuses:
-----------------------------+-----------------------------
Comment (by schlessera):
Following up on further discussion with @rmccue , I want to detail a
specific use case here, to illustrate why having a custom autoloader in
Core would probably cause issues in the future, as this does not seem to
be clear for everyone.
PHP has a very strict limitation in that each class can only ever be
defined once. So, if you try to define a class a second time, you'll get
an error.
Using an autoloader will remove that error, as the class definition is
only loaded the first time the class is encountered and is not known yet.
This creates another problem though. If you still have two class
definitions with the same name, you don't know which one will get loaded.
The autoloader will just load the first `require` statement it encounters,
and never see the second definition. This is no issue if both of the class
definitions are the same, but if you have `AClass` v1.0.0 & `AClass`
v2.0.0, you can't be sure which one will get loaded. If v1.0.0 happens to
be encountered first, all code relying on v2.0.0 will produce random
errors, which are hard to debug, because they might not even appear in a
consistent way.
Every autoloader implementation will face this issue.
What is currently considered best practice (mostly used for larger
projects), is to have Composer deal with generating the autoloaders, and
let it do so recursively from the site root (a site-wide Composer
install). Composer will generate 1 single autoloader that will include the
requested autoloaders at each sub-level, and always try to compare the
version requirements to make sure that such an issue as described above
can not happen. In this scenario, the WordPress Core, also being part of
the site root, is also pulled in via Composer.
If it encounters a conflict, it will immediately throw an error, which is
much preferable to bugs that you can hardly replicate. So, generating the
autoloader through Composer will either work reliably, or immediately
throw an error pointing you to the exact plugin/theme/library that is
causing an issue.
If you now include a custom autoloader within WordPress Core, Composer
will not be able to include this autoloader in its set of checks. So,
plugins' libraries' versions will not be verified against WordPress'
libraries' versions, and the WordPress Core autoloading code will not be
included in the one generated at the site root.
You can not even control anymore which autoloader will get precedence,
because the loading order of the autoloader does not equal the loading
order of their respective classes. As the classes are only loaded when
they are actually needed to be referenced, you might get either one,
depending on what exact path you ran through the codebase. So you'll end
up with completely unreliable code that might break without any readily
apparent patterns.
I am currently one of the people who are heavily using Composer with such
a site-wide autoloader with large projects. This all works perfectly (and
much better than any pre-Composer code), as long as the libraries (Core,
plugins, themes, ...) either include a Composer autoloader, or no
autoloader at all.
The reason why this is used is because there's no other way to get
different sets of autoloaders to work reliably otherwise, because of this
inherent PHP limitation. There's namespaces to avoid collisions to even
happen at all, but they only work for a certain category of code. For code
such as reusable libraries, which might be used in several places at once
(Core + 5 plugins, each working with the same library), you are certain to
have the exact same namespace used in several locations, and they cannot
be resolved properly through the autoloader alone. An external check has
to be made to ensure that they never want to include conflicting versions,
there's no way around that.
So, considering the above, my assertions would be that:
* '''Reliable autoloading in PHP will eventually need namespaces +
Composer + dependency management'''
* '''A custom autoloader is certain to negatively impact reliable
autoloading in PHP'''
'''Note:'''
''I did not want to talk about dependency management here to not veer
discussion into the wrong direction. However, my last discussion with
@rmccue made me aware that it cannot be completely ignored, as autoloading
for an entire project (not just WP alone) cannot possibly work reliably
without dependency management. And while I only want to discuss a Core
autoloader for now (so please don't focus on the dependency management
part now), I felt I needed to explain my reasons why I think a custom
autoloader would prove to be problematic in the future. Only considering
Core in isolation will not reveal these issues.''
--
Ticket URL: <https://core.trac.wordpress.org/ticket/36335#comment:44>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list