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