Make WordPress Core

Opened 12 years ago

Closed 11 years ago

Last modified 11 years ago

#21300 closed feature request (maybelater)

Implement autoloader compatible with PSR-0 / PSR-4 for plugins and themes

Reported by: dave1010's profile dave1010 Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Bootstrap/Load Keywords:
Focuses: Cc:

Description

To provide more compatibility with other frameworks, it would be great if WordPress implemented an autoloader compatible with PSR-0. Plugins and themes could then register namespaces or prefixes with the autoloader.

I believe this could be implemented without any BC breaks.

Details of the PSR-0 standard:
https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md

Change History (23)

#1 @nacin
12 years ago

By registering, I imagine you mean the code that implements spl_autoload_register(). SPL can be disabled before 5.3, so we can't consider it to be widely available. I suspect we will look into autoloading and PSR-0 when moving to PHP 5.3 is more than just a theoretical discussion — I don't see a minimum requirements change occurring before 2014, at the very earliest.

#2 @scribu
12 years ago

  • Component changed from Filesystem to General
  • Summary changed from Implement autoloader compatible with PSR-0 to Implement autoloader compatible with PSR-0 for plugins and themes

Let's be clear that this would only work with plugin/theme code. Core classes are not named "correctly" according to PSR-0 and to rename all of them is simply not feasible.

Maybelater?

#3 follow-up: @dave1010
12 years ago

At first I had hoped that core classes could be made compatible too but a quick grep shows around 200 classes in a clean WP install, with fairly inconsistent naming (https://gist.github.com/3135160). A long-term future issue may be to try to clean these up (WordPress 4.0?). An autoloader just for plugins and themes would still be great and encourage consistency.

Though SPL can be disabled, I believe spl_autoload_register is standard from PHP 5.1.2. I haven't seen any installations without it. Are there any other extensions (apart from mysql) that could be disabled that WordPress requires?

If SPL is likely to be disabled then the code could be wrapped in a function_exists(). Alternatively the autoloader could only be ran if PHP >= 5.3.0 (and include support for namespaces). Plugins and themes that would like to use a PSR-0 autoloader are quite likely to only support PHP 5.3 anyway. This does, however, introduce a big difference between 5.2 and 5.3, which will make testing problematic.

I still believe this is a great benefit we can give to users running PHP 5.3+ that is worth the disadvantage of the code diverging.

For reference, here's discussion on PSR-0 being implemented in Kohana and Drupal, and ticket #10493 has similar discussion about including PHP 5.3+ features in core and #14710 mentions spl_autoload_register().

Last edited 12 years ago by dave1010 (previous) (diff)

#4 in reply to: ↑ 3 @SergeyBiryukov
12 years ago

Replying to dave1010:

Are there any other extensions (apart from mysql) that could be disabled that WordPress requires?

JSON (#18015, #19524).

#5 @griffinjt
12 years ago

+1 to this. Using a PSR-0 complaint autoloader would be an excellent resource for plugins and themes to use.

I've implemented a PSR-0 compliant autoloader in Soliloquy and so far there have been no issues (over 10k+ downloads total for free and paid) that have been reported.

#6 @vivekgounder@…
11 years ago

I would like to bump this request too. As wordpress is evolving into becoming a CMS solution. An autoloader implemented for themes and plugins from the wordpress code base would be nice addition. If required I can contribute the code or I am sure many other people would already elegant solutions for implementing the autoloader.

#7 follow-up: @MikeSchinkel
11 years ago

Questions regarding this proposal: Assuming that autoloaders were enabled for plugins and themes, would that mean that each plugin and theme would move their libraries into a single autoload directory outside of their own plugin and/or theme directory, or would each plugin and/or theme would have their own directory(s) that they would have autoloaded?

If the former, would that not be a significant departure from existing WordPress architecture, especially dealing with the issues of required write permissions for code in these new directories? Would that not be problematic?

If the latter, for sites with more than a few plugins would that not result in performance concerns where the autoloader has to test the file system for file existence across many different directories every time it needs to load a file? Would that not too be problematic?

#8 @MikeSchinkel
11 years ago

  • Cc mike@… added

#9 in reply to: ↑ 7 @rmccue
11 years ago

Replying to MikeSchinkel:

Questions regarding this proposal: Assuming that autoloaders were enabled for plugins and themes, would that mean that each plugin and theme would move their libraries into a single autoload directory outside of their own plugin and/or theme directory, or would each plugin and/or theme would have their own directory(s) that they would have autoloaded?

The latter, I assume. This would more just be an implementation of PSR-0 that plugins and themes can use, the way I see it.

If the latter, for sites with more than a few plugins would that not result in performance concerns where the autoloader has to test the file system for file existence across many different directories every time it needs to load a file? Would that not too be problematic?

Most PSR-0 compliant libraries have you register a "prefix" which maps to a directory. For example, I might say that anything with the prefix rmccue_MyPlugin_ lives in myplugin/library/rmccue/MyPlugin/. This moves it from a file_exists to a strpos check, which is comparatively cheap.

+1 for this feature, by the way. I have to reimplement it in basically every plugin I have. Happy to write a patch if we're +1 on this.

#10 @nacin
11 years ago

  • Component changed from General to Bootstrap/Load

#11 @dave1010
11 years ago

  • Summary changed from Implement autoloader compatible with PSR-0 for plugins and themes to Implement autoloader compatible with PSR-0 / PSR-4 for plugins and themes

I've updated the summary to include PSR-4 now, not that it makes a lot of difference.

Would the API that plugins used to get hold of the autoloader look something like this?

$GLOBALS['wp_autoloader']->addNamespace('Acme', __DIR__ . '/src');

Without trying to derail this ticket, it would be worth considering making it easier to integrate with composer in the long term. http://wpackagist.org/ already exists and seems to be very popular (but obviously can't be used in all cases).

It would be great if plugins could have a simple file (e.g. autoload.json, in the same format as the autoload section in composer.json) that WordPress picked up automatically.

#12 follow-up: @MikeSchinkel
11 years ago

-1 on a PSR-0 or PSR-4 compatible auto-loader and on the use of Composer for plugins and themes.

Those three are all PHP "best practices," but I think most of us know that WordPress has it's own best practices that are at times conflicting with PHP best practices, and for good reason.

PHP best practices for configuration management typically target those who are setting up development, testing, staging and production environments where PHP will be deployed and used and where code is deployed by either developers or system administrator. All of those features work very well for that use-case, but WordPress has a different primary use-case.

The WordPress use-case is to have the core code deployed by site builders, many of whom cannot write PHP code, or even by automated app installers like Fantasico. And then plugin and theme code is often deployed by end-users. The WordPress use-case uses well-known directory structures, i.e. /wp-content/themes, /wp-content/plugins where self-contained and all-inclusive "packages" are installed; this minimizes users needing to be involved on a technical level.

Across plugins and themes there is potentially a large number of classes to autoload, but those classes do not follow the PSR-0/4 autoloader standard because there is no single top-level directory to load from, nor are there really vendor names. You can ignore the lack of common root and simulate vendor name with plugin name but then the class files either need to be in the root of the theme/plugin or they need to be stored in subdirectories that would be considered namespaces themselves. All-in-all this feels like a round peg in a square hole.

Another solution would be for WordPress to implement an autoloader and then every plugin and theme could opt-in to the autoloader, thus creating many top-level autoloader roots. But that seems silly because it might follow the letter of the PSR autoloaders but not the spirit, and we could end up with deeper subdirectory structures this way too.

What I would propose instead of a PSR-0/4 auto-loader is a WordPress autoloader that is much simpler, one that has only the following method:

register_autoload_path( $path_from_wp_content, $class_prefix )

It might look like this in use:

register_autoload_path( 'plugins/my-plugin', 'My_Plugin_' )

Then any plugin can register it's class paths in a 'register_autoload_paths' hook that I'd proposed to be called by WordPress just before 'init` and WordPress can collect all those files into an array and run a very simple autoloader when needed:

function _autoload( $class_name ) {
	if ( isset( $this->_autoload_classes[$class_name] ) ) {
		require( $this->_autoload_classes[$class_name] );
	}
}

And for those concerned the overhead of directory scans we could allow optional hardcoded autoloader registration like this:

register_autoload_path( 'plugins/my-plugin', array(
	'My_Plugin_Foo_Class' => 'class-foo.php',
	'My_Plugin_Bar_Class' => 'class-bar.php',
	'My_Plugin_Baz_Class' => 'class-baz.php',
));

FWIW I've implemented a library where you can see the autoloader here although it doesn't support the hardcoding I mention above.

HOWEVER, the idea of an autoloader is mostly moot anyways, at least until we make some significant changes in WordPress and/or best practices for plugin and theme development all because of how WordPress plugins and themes bootstrap themselves.

There are few non-trivial plugins or themes do not add actions or filters on the 'init' hook, and most developers I've seen using classes place these hooks in the a method of the class file. And placing hook initialization code outside of classes means separating the hook from the code it invokes making maintenance more difficult. And most of my systems I've worked on have over 50 classes and even with all those classes very few of them are without actions or filters that need to be hooked on page load. So if you autoload those classes you don't end up setting the actions and filters the code requires.

So yes we can get an autoloader, even a PSR-0/4 autoloader, but it would be a Pyrrhic victory. At least until WordPress adds an alternate approach to registering post types, taxonomies, and hooks I can't see an autoloader providing any real, practical benefit for WordPress.

BTW, for the library I mention above the approach I'm using is a different run-mode for development vs. deployment; in the former all classes are loaded and then the array of classes and class paths is serialized to a file that gets loaded when deployed for production. This works well for building sites where version control is used between development source and production deployment but would not really work well for the normative WordPress use-case of end-users adding plugins and themes on live sites.

Replying to griffinjt:

I've implemented a PSR-0 compliant autoloader in Soliloquy and so far there have been no issues (over 10k+ downloads total for free and paid) that have been reported.

Hmm. Didn't want to pick on your work here, but since you presented it as an example of an autoloader done right I figured you'd be okay to open it for discussion.

I just downloaded Soliliquy Lite and compared to PSR-0 and unless I'm missing something Soliliquy Lite is not PSR-0 compatible because it doesn't use PHP namespaces, and that's appears to be a requirement in PSR-0 (as well as in PSR-4):

- A fully-qualified namespace and class must have the following structure:
\<Vendor Name>\(<Namespace>\)*<Class Name>
- Each namespace must have a top-level namespace ("Vendor Name").

As an aside, you could add Namespaces but until core adds Namespaces and sets a precent for usage in WordPress I'm going to stick with "poor-man's namespacing" (i.e. prefixes.)

More importantly, it appears you are loading hooks in the constructor of most of your classes, and then in the main 'init' hook you are creating instances of all those classes (in the admin) or just 3 of the 9 outside the admin. And outside the admin don't appear to be creating new instances of the others. So of the two main code paths admin and front end you are always instantiating the same classes, per code path.

And in your autoloader you are using a file_exists() call before your require() call so your plugin is doing double work for each file you are loading. If you only needed to load a small subset of classes autoloading is definitely better, but if you are going to autoload every class every time anyway I'd argue you'd be better off getting rid of the autoloader and just doing direct require()s for the classes you plan to instantiate within init.

So I recommend we close this ticket as maybelater.

#13 @MikeSchinkel
11 years ago

Oh, and my issue with Composer for plugins and themes is that Composer does not map to the problem space that is user-added plugins and themes. Composer is about managing shared libraries but WordPress doesn't support shared libraries.

Plus Composer is very strict in its directory layout; it puts everything under a "vendor" directory and that is not how plugins and themes store their file, unless we were to (optionally) have vendor directories in each and every plugin and theme.

OTOH having multiple vendor directories gets around one of the main benefits of Composer IMO and that's for Composer to be able to bring in only one copy of a latest compatible version of a given library even though multiple other libraries may reference it. Basically it's the Highlander mantra.

And that's a problem because as stated above WordPress has no built-in way to manage libraries used by multiple plugins/themes, especially when the versions used are different but all the function/class name are the same. So WordPress plugins/themes really can't use reusable libraries, and reusable libraries is what Composer is about. (WordPress websites could use Composer if you ignore its opinionated directory structure, but that's not the use-case being discussed here.)

So I don't think we can apply Composer to work with plugin and theme dependencies unless and until at least WordPress provides mechanisms to share libraries across plugins/themes. I would instead like to see WordPress use some of the concepts in Composer to solve the problem in it's own WordPress-ish way, including adding a way to share libraries across plugins/themes.

#14 @nacin
11 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to maybelater
  • Status changed from new to closed

I'm not sure there's a single line in MikeSchinkel's two comments that I disagree with.

#15 in reply to: ↑ 12 @rmccue
11 years ago

Replying to MikeSchinkel:

-1 on a PSR-0 or PSR-4 compatible auto-loader and on the use of Composer for plugins and themes.

Also agreed with Mike on this one. There's plenty of ways to implement it (and I do it differently myself at times), and none of them fit the WP paradigm. On the other hand, it's trivial to implement it yourself (mine's 46 lines of code).

Also -1 on Composer for plugins/themes, but there's some interesting code in there that can be extracted for dependencies (their port of the libzypp dependency resolver).

#16 follow-up: @dave1010
11 years ago

I understand a Composer-esque vendor system isn't the WordPress way. Perhaps I shouldn't have introduced that in this ticket :-).

Replying to MikeSchinkel:

PHP best practices for configuration management typically target those who are setting up development, testing, staging and production environments where PHP will be deployed and used and where code is deployed by either developers or system administrator. All of those features work very well for that use-case, but WordPress has a different primary use-case.

Agreed. Though I think there's certain things that WordPress can do for developers who want to follow PHP best practices without hindering site builders who cannot write PHP code.

Getting back to providing an autoloader to plugins and themes:

Across plugins and themes there is potentially a large number of classes to autoload, but those classes do not follow the PSR-0/4 autoloader standard because there is no single top-level directory to load from, nor are there really vendor names.

It's up to plugin and theme authors to structure their code how they want (inside their own wp-content/plugins/foo directory). Some plugins don't use classes at all; some require_once one or 2 files in their root directory; others follow PHP best practices by using a PSR-0/PSR-4 class loader, with vendor names and namespaces. This file structure isn't defined or influenced by WordPress.

Another solution would be for WordPress to implement an autoloader and then every plugin and theme could opt-in to the autoloader, thus creating many top-level autoloader roots. But that seems silly because it might follow the letter of the PSR autoloaders but not the spirit, and we could end up with deeper subdirectory structures this way too.

This is the solution I was proposing. WordPress can't force plugins to use an autoloader, the same way WordPress can't force plugins to use $wpdb. As a developer if all my code (WordPress and other PHP) can follow the letter of the PSR autoloaders then it makes life much easier.

Composer has multiple autoloaded roots in vendor. WordPress would have them in wp-content/plugins. I don't see how that's particularly different. Is plugin authors using deeper subdirectory structures an issue?

What I would propose instead of a PSR-0/4 auto-loader is a WordPress autoloader that is much simpler, one that has only the following method:
register_autoload_path( $path_from_wp_content, $class_prefix )
It might look like this in use:
register_autoload_path( 'plugins/my-plugin', 'My_Plugin_' )

This is virtually identical to registering with a PSR-0/4 auto-loader. Requiring the plugin to know it's path from wp-content seems like a small overhead over just using dirname(__FILE__) or __DIR__ though. I'm all for WordPress providing a simpler API to an autoloader, but it would be great if the actual autoloader was exposed too.

Then any plugin can register it's class paths in a 'register_autoload_paths' hook that I'd proposed to be called by WordPress just before 'init` and WordPress can collect all those files into an array and run a very simple autoloader when needed

Is there any reason plugins couldn't register and get access to autoloaded classes immediately if they wanted? Authors could always wrap the call to register_autoload_path() in an add_action() if they wanted.

HOWEVER, the idea of an autoloader is mostly moot anyways, at least until we make some significant changes in WordPress and/or best practices for plugin and theme development all because of how WordPress plugins and themes bootstrap themselves.

PSR autoloading is already best practices for PHP in general, which I don't see any harm in WordPress at least providing minimal support for. No BC breaks are required and it's purely opt-in.

Plugins can already bootstrap themselves with their own PSR autoloader, or they could use one provided by WordPress. WordPress provides useful tools to plugins (like $wpdb) so they don't have to reinvent the wheel every time. An autoloader would be a good addition IMO.

Grepping a recent site build, there are 9 plugins (out of 22) that have calls to spl_autoload_register! How many plugins would use their own DB abstraction layer if WordPress didn't provide $wpdb?

There are few non-trivial plugins or themes do not add actions or filters on the 'init' hook, and most developers I've seen using classes place these hooks in the a method of the class file. And placing hook initialization code outside of classes means separating the hook from the code it invokes making maintenance more difficult. And most of my systems I've worked on have over 50 classes and even with all those classes very few of them are without actions or filters that need to be hooked on page load. So if you autoload those classes you don't end up setting the actions and filters the code requires.

I don't think I follow this. Autoloading is just a more consistent and maintainable way of requiring classes. Instantiating them shouldn't be affected.

So yes we can get an autoloader, even a PSR-0/4 autoloader, but it would be a Pyrrhic victory. At least until WordPress adds an alternate approach to registering post types, taxonomies, and hooks I can't see an autoloader providing any real, practical benefit for WordPress.

As a plugin developer, having a standard autoloader would be a big victory. I really don't think the ability to to improve things like post type registration would be harmed by making this first step.

#17 in reply to: ↑ 16 @MikeSchinkel
11 years ago

Replying to dave1010:

I understand a Composer-esque vendor system isn't the WordPress way. Perhaps I shouldn't have introduced that in this ticket :-).

Oh I hope you did not take any of my comments as personal criticism. I too wanted exactly the same until recently after I implemented autoloading and tried to implement composer, and learned all that I did about it.

...I think there's certain things that WordPress can do for developers who wants to follow PHP best practices without hindering site builders who cannot write PHP code.

Agreed, in concept. Figuring out exactly what those things are is/has been the difficult part.

It's up to plugin and theme authors to structure their code how they want (inside their own wp-content/plugins/foo directory).

Yes.

This is the solution I was proposing. WordPress can't force plugins to use an autoloader, the same way WordPress can't force plugins to use $wpdb.

I think I wrote my comments poorly, because forcing developers was not something I was suggesting, and did not mean to imply.

As a developer if all my code (WordPress and other PHP) can follow the letter of the PSR autoloaders then it makes life much easier.

Yes your code can be structured to follow the letter of the PSR. My assertion is that would mean you would need to split related code into two files each in order to load hooks but not load their related classes, and it would add required complexity to a plugin's directory if the developer chose to use the autoloader.

And yes it is the developer's choice, but an autoloader is pretty simple to implement so if a developer want to use one in their plugin nothing is stopping them from doing so right now.

The questions about including in core are: Would the required structure be something WordPress core would want to advocate for, and would the benefits of the autoloader be worth it in the 80 percentile case? My opinion is "no" would be the answer to both of those questions.

And personally I do not think there's a benefit to an autoloader in core at this stage of WordPress' evolution. Maybe later, but not now.

Composer has multiple autoloaded roots in vendor. WordPress would have them in wp-content/plugins. I don't see how that's particularly different.

When I tried implementing Composer and getting the directories to work in a WordPress friendly way required significantly complexity, way more than it should require and really fighting the natural approach of Composer. Take a look at my StackOverflow question and my own followup answer. Note that I was discussing use with (my own concept of) "libraries" but the structure would be the same for plugins. IMO that's too much complexity to bake into WordPress core.

This is virtually identical to registering with a PSR-0/4 auto-loader.

Virtually identical and identical are like horseshoes and hand-grenades when it comes to specifications. If you are following a spec you either follow it exactly or don't say you are following it. There's a huge benefit to adopting a standard, but not when you have to fit a square peg in a round hole.

Requiring the plugin to know it's path from wp-content seems like a small overhead over just using dirname(__FILE__) or __DIR__ though. I'm all for WordPress providing a simpler API to an autoloader, but it would be great if the actual autoloader was exposed too.

That's just how I presented it in the example. The idea could work with either relative or absolute URLs, developer preference.

Is there any reason plugins couldn't register and get access to autoloaded classes immediately if they wanted?

Yes, but for what benefit? If you are going to always load specific classes why not use a require() instead of an autoloader? Yes development might be simpler but I think you should at least hard code those require()s for deployment.

Authors could always wrap the call to register_autoload_path() in an add_action() if they wanted.

Not following why this would have value.

PSR autoloading is already best practices for PHP in general, which I don't see any harm in WordPress at least providing minimal support for. No BC breaks are required and it's purely opt-in.

Because as I said, it's mostly a moot point given the current best practices in the WordPress community. If WordPress were not so dependent on hooks being loaded on every page load then it would be different. But then it would not be WordPress.

That said, you'll have to convince the core team members to do it if you want; I'm just like you here, another guy offering his opinion.

Plugins can already bootstrap themselves with their own PSR autoloader, or they could use one provided by WordPress. WordPress provides useful tools to plugins (like $wpdb) so they don't have to reinvent the wheel every time. An autoloader would be a good addition IMO.

How do you get an autoloader to be able to not load more than 50% of the classes on each page load? That's the question. If we can tackle that then it might be a lot more clear that adding the extra overhead (in load time, maintenance cost, support issues when people autoloaded classes and hooks didn't get fired, etc.) would be worth it.

How would I approach it? I'd specify some well-known constants and methods for a class like self::POST_TYPE, self::ARGS() and self::HOOKS() that allow a developer to register post types and add hooks "declaratively" instead of using procedural code, and then on plugin activation I would load all classes and cache the information to allow all registrations and fixups on normal page load to occur without having to load any of the classes in which the information was defined.

But that approach is nothing like anything else being done in core so I doubt the core team would adopt that approach in the foreseeable future.

Grepping a recent site build, there are 9 plugins (out of 22) that have calls to spl_autoload_register! How many plugins would use their own DB abstraction layer if WordPress didn't provide $wpdb?

I'd really like to have a look at those plugins to see if in fact they are really benefitting from autoloading, or just instantiating most classes on every page load anyway. If I'm correct and it's the latter, maybe what we need to do instead is to preach the people should not use autoloaders with WordPress (unless of course they address the issues I'm bringing up in their own plugin.)

I don't think I follow this. Autoloading is just a more consistent and maintainable way of requiring classes. Instantiating them shouldn't be affected.

What I'm saying is that you get no benefit from an autoloader if you load the class files for each class on every page load anyway. You will end up loading any classes that contain hooks that must be added every page load.

I mentioned the instantiation only because that's what triggers an autoloader to load class files.

I really don't think the ability to to improve things like post type registration would be harmed by making this first step.

I don't follow how this relates.

As a plugin developer, having a standard autoloader would be a big victory.

I'll say it again, it would be a Pyrrhic victory if the result is more complexity, increased page load times on average and increase support issues where plugins are published but they forget to test all logic paths and thus don't load classes that have needed hooks.

BUT, who knows? Maybe I'm all wrong. Suggestion: If you believe this is important why not implement it as you think it should work and submit a patch. Then we can discuss specifics instead of just bikeshedding. And working code is a lot closer to being committed to core than ideas.

#18 @Denis-de-Bernardy
11 years ago

Fwiw, here's a simple autoloader that I'd love to see added to WP, so as to not need to constantly add the same lines of code in each plugin.

Not that the lines are very long:

# PSR-4 Autoloader
spl_autoload_register(function($class) {
    if ($class !== strstr($class, __NAMESPACE__ . '\\')) return;
    $file = substr($class, strlen(__NAMESPACE__));
    $file = str_replace('\\', DIRECTORY_SEPARATOR, $file) . '.php';
    $file = __DIR__ . DIRECTORY_SEPARATOR . 'src' . $file;
    if (file_exists($file)) {
        require $file;
    }
}, true);

Still, I'd not need to constantly remember to copy/paste them if WP version offered something similar, e.g.:

class WP_Autoloader
    function __construct($namespace, $path) {
        $this->namespace = $namespace;
        $this->path = $path;
    }

    function load($class) {
        if ($class !== strstr($class, $this->namespace . '\\')) return;
        $file = substr($class, strlen($this->namespace));
        $file = str_replace('\\', DIRECTORY_SEPARATOR, $file) . '.php';
        $file = $this->path . $file;
        if (file_exists($file)) {
            require $file;
        }
    }
}

wp_register_autoloader($namespace, $path) {
    $loader = new WP_Autoloader($namespace, $path);
    spl_autoload_register(array($loader, 'load'), true);
}

Or perhaps a variation of the above that accommodates prefixes instead of namespaces indifferently (I'll happily supply the patch if it's +1'ed). At any rate, I like this idea and think we should re-open the ticket.

#19 follow-up: @Denis-de-Bernardy
11 years ago

Moreover, I'd argue that the main point in adding this is to guide plugin and theme devs into some level of structure when they develop. It would be *very* sweet if, instead of needing to dig through a hodgepodge of files in order to locate a class, one could find Foo_Bar_Baz in Foo/Bar/Baz.php.

#20 in reply to: ↑ 19 ; follow-ups: @MikeSchinkel
11 years ago

Replying to Denis-de-Bernardy:

It would be *very* sweet if, instead of needing to dig through a hodgepodge of files in order to locate a class, one could find Foo_Bar_Baz in Foo/Bar/Baz.php.

Please don't. Deep directory structures are a real pain to deal, especially when you are talking about a small number of files like with most plugins.

That said, struggling to find classes is a problem I never see. What editor do you use? Doesn't your editor give you tools to find classes easily?

#21 in reply to: ↑ 20 ; follow-up: @Denis-de-Bernardy
11 years ago

Replying to MikeSchinkel:

Please don't. Deep directory structures are a real pain to deal, especially when you are talking about a small number of files like with most plugins.

But then, you and I mustn't be dealing with the same plugins on a day to day basis.

That said, struggling to find classes is a problem I never see. What editor do you use? Doesn't your editor give you tools to find classes easily?

Textmate, and it does.

Let me put it this way, though: my main customer at the moment is running a nuclear wasteland comprising of ~80 mostly forked plugins and four themes due to hard-coded references and child themes all over the place, none of them up to date, with a grand total of ~8000 files full of buggy spaghetti code.

It's not pretty, and the first thing that came to my mind was -- duh! -- to drop WP entirely and rebuild his entire site on top for a sane PHP framework and Postgres.

#22 in reply to: ↑ 21 @MikeSchinkel
11 years ago

Replying to Denis-de-Bernardy:

Let me put it this way, though: my main customer at the moment is running a nuclear wasteland comprising of ~80 mostly forked plugins and four themes due to hard-coded references and child themes all over the place, none of them up to date, with a grand total of ~8000 files full of buggy spaghetti code.

LOL! Well, you've definitely got me beat for suckiest main client, at least as far as the code you have to work on. Ugh.

#23 in reply to: ↑ 20 @F J Kaiser
11 years ago

Replying to Denis-de-Bernardy:

It would be *very* sweet if, instead of needing to dig through a hodgepodge of files in order to locate a class, one could find Foo_Bar_Baz in Foo/Bar/Baz.php.

It would be *much* sweeter if we could simply write

use WCM\FooBarPlugin\Controllers\PostLoopController;

and then instantiate $loop = new PostLoopController();.

Replying to MikeSchinkel:

Please don't. Deep directory structures are a real pain to deal, especially when you are talking about a small number of files like with most plugins.

That's why we got PSR-4 nowadays. Less deep nested than PSR-0.

Replying to Denis-de-Bernardy:
Keep in mind that this (your example autoloader) isn't all of it. We'd need a logger as the PSR-3 specs state that there should be no interruption of the loading process and later autoloaders should be given the chance to have their own attempts at loading files. And as debugging without errors, warnings and notices is a guessing game, it won't work without a PSR-3 compatible logger.

Replying to @Everybody:

Proposal: As PSR-4 keeps the rule of two namespace levels for vendor and bundle/package, we could easily use one big namespace WPPlugin that points to ~/wp-content/plugins (or whatever is defined) and then add all plugins into vendor folders. Example:

namespace WPPlugin\HyperMegaSEO;

Summed up: We need a PSR-4 compatible autoloader to not have unnecessary deeply nested folder structures. It needs to work together with other PSR-4 compatible autoloaders and it has to be silent and has a PSR-3 compatible logger (I'm not going to punch anyone for that Singleton!) for debugging.

Also it has to play nice with other PHP-fig/PSR compat autoloaders. Else you would break all my plugins that use stuff like Guzzle or that parts that I reuse from (for e.g.) Symfony2, Zend or elsewhere from user land.

And Composer has proven to work seamlessly in WordPress installs (powered by at least PHP 5.3), I don't see a reason why we should cook our own soup. We have to play nice with other autoloaders anyway to not break tons of installs. So let's face it: We have jQuery in core because it's easy to use, widely accepted and has a big contributors base and on going development. The same goes for backbone.js. Why not use Composer?

Additional notes and thoughts: Most of the major PHP frameworks already use Composer: Zend2, Symfony2, Laravel. IIRC Yii and CakePHP use an incompatible one (dunno if that's still true) while the one from Phalcon works nicely when switching to Composer. Drupal8 will be shipped with Composer and make use of Symfony2 bundles. Imho this will have a huge impact as it's plugin/module (whatever it's called) base massively increase overnight. They will have thousands of well coded (and tested) bundles at their fingertips. If we want to keep pace with what's happening there, I don't see any way around using Composer as developing and maintaining our own Autoloader (plus a package/dependency manager that reaches over the boundaries of wp.org) would take too long and would not be worth the effort. We already have too many APIs that need constant polishing and love.

Note: See TracTickets for help on using tickets.