[wp-trac] [WordPress Trac] #36335: Next generation: core autoloader proposal
WordPress Trac
noreply at wordpress.org
Mon May 16 09:57:26 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: | Focuses:
-----------------------------+-----------------------------
Comment (by tfrommen):
Hey Ryan,
thanks a lot for your comment, and even more for the time and effort spent
around it.
There are several things that I don't quite like, so I'm going to discuss
them here. I really do try to be as constructive as I can, though. :)
> I think whether we adopt Composer usage or not isn't hugely relevant to
this conversation...
In my opinion, it '''is''' relevant in that we really should not (in fact:
'''must''' not) introduce anything incompatible with Composer as long as
there is even the slightest chance we might switch over to Composer one of
these days.
> I don't think the current implementation is appropriate for core. It's a
bit too heavy and general-purpose.
I don't see anything bad with general purpose software
(architecture)—as long as serving general purpose doesn't mean
including lots of stuff that is only relevant for a tiny fraction of use
cases, of course.
The current state of our implementation is definitely not set into stone.
However, I don't see anything really heavy and/or unnecessary there.
Would you mind indicating what parts you find superfluous (for the start)?
> I have an alternative implementation that tries to stay as lightweight
as possible.
Some comments on your code then...
'''Consistent return type'''
Can we please try to not include any more multi-return-type functions
(without an actual, good reason for doing so)...?
Making `get_path()` return an empty string `''` can only be understood as
''I didn't find a file (path) for the ''thing'' you are trying to load'',
can it?
So we should just stick with `string`.
Even if core WordPress doesn't come with interfaces (or traits), it makes
sense not to exclude these Structural Elements.
This would lead to these two changes:
* `$class` would be either `$fqn` (fully qualified name) or `$fqsen`
(fully qualified Structural Element name);
* ''ClassMap'' would be just ''Map''.
'''More flexible code'''
I would like to not include the hard-coded `class-` prefix into the
`WP_Autoload_Prefixed` class, but rather implement the class like so:
{{{#!php
<?php
class WP_Autoload_Prefixed implements WP_Autoload_Handler {
protected $path;
protected $path_prefix;
protected $prefix;
public function __construct( $path, $path_prefix = '', $prefix =
'' ) {
$this->path = trailingslashit( $path );
$this->path_prefix = strtolower( $path_prefix );
$this->prefix = strtolower( $prefix );
}
public function get_path( $fqn ) {
$fqn = strtolower( $fqn );
if ( $this->prefix && 0 !== strpos( $fqn, $this->prefix )
) {
return '';
}
$filename = $this->path_prefix . str_replace( '_', '-',
$fqn ) . '.php';
return $this->path . $filename;
}
}
}}}
That way, one could also use the class for things like `class.foo.php` and
`interface-foo.php`.
'''Prefix global functions'''
We should not introduce a new unprefixed global function
`register_autoloader()`. This will eventually break things here and there,
so we should call it something like `wp_register_autoloader()`.
I guess the `file_for_class` if just for your table, right?
'''Improve `__autoload()`'''
`$spl_autoloaders` is global, so anyone can put into it whatever they
like. So we should check for `is_callable` inside `__autoload()`.
Also, we should really not check for `class_exists` for several reasons.
First, it's restricted to classes only. Second, it's too heavy, and even
unnecessary, because the autoload function already returns something we
can check against.
This would make `__autoload()` something like this:
{{{#!php
<?php
function __autoload( $fqn ) {
global $spl_autoloaders;
foreach ( $spl_autoloaders as $autoloader ) {
if ( ! is_callable( $autoloader ) ) {
continue;
}
if ( call_user_func( $autoloader, $fqn ) ) {
// If it has been autoloaded, stop processing.
return true;
}
}
return false;
}
}}}
'''Improve `spl_autoload_register()`'''
You check if the passed callback is actually callable, okay. But you
continue to just add it to the global in case the function shouldn't throw
any exceptions.
In fact, something like this would be better:
{{{#!php
<?php
function spl_autoload_register( $autoload_function, $throw = true,
$prepend = false ) {
if ( ! is_callable( $autoload_function ) ) {
if ( $throw ) {
// String not translated to match PHP core.
throw new Exception( 'Function not callable' );
}
return false;
}
global $spl_autoloaders;
// Don't allow multiple registration.
if ( in_array( $autoload_function, $spl_autoloaders ) ) {
return false;
}
if ( $prepend ) {
array_unshift( $spl_autoloaders, $autoload_function );
} else {
$spl_autoloaders[] = $autoload_function;
}
return true;
}
}}}
'''Improve `spl_autoload_functions()`'''
Since `$spl_autoloaders` is a global, and since we don't want to argue
with SPL, we should make sure we're returning an array.
{{{#!php
<?php
function spl_autoload_functions() {
global $spl_autoloaders;
return is_array( $spl_autoloaders ) ? $spl_autoloaders : array();
}
}}}
> It implements the bare minimum to support autoloading core itself, which
is likely also useful for plugins, but isn't necessarily designed to be.
The main difference between the currently proposed implementations as well
as the according discussions lies with '''who''' is '''when''' able to use
the autoloader '''for what'''.
As long as the end goal is a central autoloader that '''can''' be used for
core WordPress as well as plugins and themes, I'm totally fine with
whatever route we take.
However, we really should think about from what amount (and type) of
changes we could benefit the most, and what types fo changes do make most
sense when.
> let's use `spl_autoload_register` directly rather than implementing our
own autoloading stack on top of it.
Well, that would be awesome, wouldn't it. :)
--
Ticket URL: <https://core.trac.wordpress.org/ticket/36335#comment:31>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list