On Sat, Jul 6, 2024, at 1:12 AM, Mike Schinkel wrote:

> <epiphany>
>
> Reading this however caused me to ponder things certain people has said 
> recently — and many people have said for years on this list — and I 
> think I am recognizing something that I have always known but never put 
> the pieces together before.
>
> Many (most?) people on PHP Internals view WordPress coding standards as 
> bad and some even view addressing WordPress developers needs as bad for 
> PHP. And in general I concur that those people are reasonably justified 
> in their belief WordPress' coding standards are not the standards that 
> PHP developer who want to do professional level software engineering 
> should aspire. 
>
> And since many (most?)* *PHP Internals members generally do not 
> experience the issues that WordPress developers have they do not 
> recognize that they are issues; IOW, *"out of sight, out of mind." *
>
> I also think some list members tend to dismiss WordPress developers 
> pains as unimportant and/or think that addressing those pains have will 
> harm* *PHP. 
>
> (BTW, I recently had a dialog off-list with someone who wrote in an 
> email that *"Wordpress is an exception, but nobody these days treats 
> WordPress as a valid example to do anything. It is an ancient piece of 
> legacy code that has no bearing on modern situation and it's their 
> problem to deal with." *So I am not just erecting a straw man here.)
>
> But I think what most may not consciously recognize is that* WordPress 
> is a different type of web app* than an app build using Symfony or 
> Laravel and deployed by its developers, or by some other professional 
> developer. 
>
> WordPress differs from the apps many *(most?)* developers on PHP 
> Internals work with in the following way:
>
> WordPress = *User-managed app*
> Most = *Developer-managed apps*
>
> In a* Developer-Managed app* developers choose which 3rd party 
> functionality will be incorporated into their sites whereas with a 
> *User-managed app* users choose which 3rd party functionality will be 
> incorporated into their site. And that is the KEY difference. 
>
> So I am wondering if we can get people on this PHP Internals list who 
> dismiss the needs of WordPress developer BECAUSE it is WordPress to 
> recognize that User-Managed apps ARE a class of PHP applications have 
> needs that **deserve** to be addressed?  
> *
> *
> Two (2)* unmet needs of User-Managed apps *that *"standard" *PHP 
> currently does not address come to mind:
>
> User-managed apps needs to be able to handle both:
> *
> *
> 1. *User-added add-ons* *("plugins" in WordPress, "modules" in Drupal) 
> *that have conflicting dependencies, and
>
> 2. *Add-on directory structures *that do not follow a PSR-4 directory 
> hierarchy.
>
> As for #2, even if those apps could rearchitect their existing 
> directory structure they cannot realistically be expected to do with 
> because of the huge BC issues their users would experience. 
>
> And newly created User-managed apps may still find that a PSR-4 
> directory structure is not in the best interest of their project or 
> their users. To elaborate, PSR-4 generally assumes that ALL code goes 
> into ONE hierarchy and that any and all code that will be autoload gets 
> placed in that hierarchy.
>
> But with add-ons it makes a lot more sense to have the entire add-on 
> contained in its own add-on directory. This is exactly where PSR-4 
> breaks down with respect to User-managed apps.
>
> Sure, you can have multiple PSR-4 autoloader root directories, but that 
> does not scale well to websites with a large number of add-ons as many 
> WordPress sites I worked on used. Some had over 100 plugins.  With a 
> hierarchy of autoloader maps that Michael Morris is proposing WordPress 
> could collect up all the maps and create one map every time a plugin is 
> added, updated or deleted.
>
> </epiphany>

I am going to jump in here on this point specifically, because it seems to be a 
mix of genuinely insightful observation (though not unique) and uninformed FUD.

Some context: I haven't seriously used Wordpress in, ever.  However, I was a 
Drupal lead developer for many years, and wrote, among other things, Drupal's 
DBAL, Drupal's first autoloader, Drupal's PSR-3 implementation, was involved in 
Drupal's file organization guidelines for Drupal 8+ (when Drupal adopted a 
PSR-0/4 autoloader), and led the Drupal 8 "Modernize all the things" effort.  
So I do have some non-trivial experience in this area.

First, you're correct that there is an architectural difference between 
"projects that assume the owner has CLI access" and those that do not.  You are 
also correct that most of the Internals crowd comes from the former.  

However, I don't think it's fair to say that's why Internals folks "dismiss" 
Wordpress generally.  We dismiss Wordpress generally because

1. WP actively harms the PHP community by encouraging the use of ancient PHP 
versions with known security issues.
2. WP's code base actively avoids using what have been considered known 
best-practices (in either type of application) for 15 years.
3. WP's core team actively avoids being involved in Internals to collaborate on 
how to make the language better for them.  In fact, they've made it very clear 
that PHP is a legacy implementation detail and Node/client-side JS is where 
their focus is.  The only WP-affiliated person I can even think of that has 
been a semi-regular Internals contributor is Juliette (whose participation I 
very much welcome).

That said, it was recently pointed out to me that Automattic is the top 
contributor to the PHP Foundation (https://opencollective.com/phpfoundation), 
which is very much appreciated and nothing to sneeze at.

And yes, I fully agree that any module/package/thing needs to take into account 
the needs of both types of projects.  As Rowan has repeated, that means keeping 
the impact of any changes minimal, so that the Composer ecosystem and WP 
ecosystem can TYPO3 ecosystem can build their own tooling on top of it.

You'll note I did not list Drupal there.  That's because modern Drupal is 
composer-based, and has been for many years.  I was the one that pushed hard 
for adopting Composer, its autoloader, and PSR-4 for Drupal 8 in the first 
place.  While much of the transition happened after I left the project, the 
groundwork is over a decade old.  Composer is the preferred way to use Drupal, 
and to install Drupal modules.

So the line is not as hard between those two models as you might think.

> PSR-4 generally assumes that ALL code goes 
> into ONE hierarchy and that any and all code that will be autoload gets 
> placed in that hierarchy.

This is flatly untrue, and belies a considerable ignorance about how PSR-4 and 
Composer work.

PHP supports multiple autoloader callbacks, and has for over 15 years.  You 
absolutely can register multiple if you'd like, using whatever logic you like. 
PHP will call each one in turn until the class is loaded.

All PSR-4 does is specify a directory structure that makes a common autoloader 
stupidly simple to write.  It's just a few lines long.  But you can already do 
any logic you like for an autoloader.  PHP doesn't care.

However, nothing precludes you from registering multiple autoloaders, all using 
PSR-4, all using a different path root.  That has been trivially simple to do 
since 2009.  (OK, it was PSR-0 at the time, but the implications here are the 
same.)  So your statement above about "all code goes into one hierarchy" is 
simply flat out false.

Of course, as you note, registering lots of separate autoloaders has a 
performance impact.  That is true.  Which is why I don't think anyone actually 
does that.

Composer, for instance, registers a single autoloader only.  That autoloader 
internally tracks many dozens of PSR-4 roots (one for each package, sometimes 
two per package), as well as files that will get force-loaded when the 
autoloader is registered, plus generated classmaps.

Using class maps, you can put a hundred classes in one file and composer can 
handle that *today*.  That has always been possible.  That no one does so is a 
sign that there's little reason to do so in most cases.

In fact, if you use an optimized/dumped autoloader, then Composer simply builds 
an internal giant lookup table of what class maps to what file.  PSR-4 is then 
*completely irrelevant* at runtime.  It's already one giant O(1) lookup map.  
That can be done *today*.  That *is* done today.

But what about systems like Drupal, that don't put code in `/vendor/`?  Drupal 
ties directly into Composer via its API,and has done so for a decade.  Drupal, 
a "user-managed application" as you describe it, has Composer baked in at a 
core level.

It looks like the integration has evolved considerably since I was last 
involved, but have a look at:

https://git.drupalcode.org/project/drupal/-/tree/11.x/composer

As of when I last looked at it (around 2016 or so), Drupal registers its module 
code roots with Composer directly, and then Composer takes over from there and 
integrates Drupal's code into its own indexes.  There is still only one single 
autoloader registered with PHP.  This is entirely fine.

I would encourage you to do your research before speaking 
pseudo-authoritatively on this topic, as you clearly are mis-stating both the 
problem and the tools involved today.

What Drupal does not do is address the "different dependency version" question. 
 And neither does Wordpress.  Or TYPO3.  Or any other project.  Because that's 
a core PHP limitation.  

In Python, every module is really just an object with a big dictionary of the 
functions/classes it has.  When you "import" a symbol from another module, the 
engine is doing little more than `$this['foo'] &= $that['foo']`.  That's a core 
part of how the language works.  (I'm not sure of Javascript's details, but I 
suspect from using it that it's similar.)

PHP works very very differently.  PHP has a single global list of symbols.  
(Well, two, for classes and functions.)  Namespaces are just syntax sugar over 
very-long-names, nothing more.  There is no "local symbol table," so having 
different local symbol tables point to different code blocks using the same 
name is not even conceivable.

If you want to change that, and give PHP multiple local symbol tables, then 
autoloading... is utterly irrelevant.  The question there is "how can we 
introduce local symbol tables in the engine without requiring 10 million 
developers to rewrite the file header of 1 billion PHP files across the world?" 
 Honestly, I'm not convinced its even possible. Someone with more engine 
knowledge than I could be able to find away, maybe, but I am skeptical.  If 
it's even possible, I suspect it would be an absurdly large amount of work and 
necessarily include many hard BC breaks.

If you'd like to prove me wrong, go for it.  But that's the problem to address. 
 Debating file paths is about four steps down the line before it's even 
relevant.  And even then... if you can't make a PSR-4-organized package (of 
which there are several hundred thousand) slot into that new model comfortably 
with zero effort on the part of the package author, it's doomed.

So please, spare us the ill-informed descriptions of how you think autoloaders 
work, when you have demonstrated you do not know how they work.  

Spare us the litany of complaints about PSR-4 when you have demonstrated you 
don't know what PSR-4 says.  

Spare us the gnashing of teeth about how hard it is to use a Wordpress plugin 
that hasn't been updated in 10 years with a modern plugin because the former is 
still using a 10 year old abandoned version of some library, when that's not 
PHP's problem, that's a Wordpress maintenance problem.

If you want to move this effort forward, here's your todo list:

1. Do some research in the engine to determine if local symbol tables are even 
possible without rewriting the engine.
2. Work through the highly complex logic of handling three layer overlapping 
transitive dependencies in a diamond pattern with conflicting version 
requirements.
3. Investigate the performance impact of maintaining multiple versions of the 
same code in memory at once, when the order they get loaded will vary by 
request.
4. Think through how you'd support *both* composer-based and "user managed" 
applications with such a model, especially projects that are already 
architecturally a decade out of date (like Wordpress).

When you have a proven that it's even possible to have multiple local symbol 
tables, we can talk.  Until then, please spare us.

--Larry Garfield

Reply via email to