> On Jul 6, 2024, at 8:01 PM, Michael Morris <tendo...@gmail.com> wrote:
> 
> Some context from where I'm coming from.  I have been working exclusively in 
> React, NodeJS and Go up till about a year ago, and in Drupal before that - it 
> being 10 years since the last time I looked at WordPress. I need work though, 
> and I was offered a job where about two-thirds of my workload is a massive 
> WordPress site that has grown well outside the scope WordPress does best.  So 
> I've been getting used to it again and added some ulcers along the way.

Yes, a university semester could be filled with the dynamics of open-source 
when a project's user base and those overseeing its governance diverge. #fwiw

BTW, you don't happen to be working for my last WordPress client, are you? 😲

> <epiphany>
> ...
> Many (most?) people on PHP Internals view WordPress coding standards as bad 
> and some even view addressing WordPress developers needs as bad for PHP....
> 
> I really don't want to get into that crossfire. WordPress is the 800lb. 
> gorilla of the PHP app world having more server market share that is dominant 
> - how dominant depends on who you ask. The most conservative estimate I've 
> seen is about half of PHP sites are running WordPress, and the most pro-WP 
> quote I saw claimed it has around 80% share.

The reality is it does not matter if you want to or not, by arguing for a 
feature on PHP Internals that is needed more by user-managed apps like 
WordPress than developer-managed apps, you have stepped into said crossfire.

You do not get to pick your reality, your reality picks you.

>>   B/ = './path/to/B/'
> 
> It is not clear to me what a trailing slash means, and especially why it is 
> needed on the left-hand side?
> 
> This is taken from the JavaScript importmap specification, but it exists to 
> cordon off direct file includes from directory includes. Original spec here: 
> https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap
>  
> And why slash here when namespaces use backslash?
> 
> Because it's the end of a path and unless you're on Windows directories are 
> delimited with /. They aren't the same thing
>  
> Also, as someone raised on DOS and then Windows only "converting" in 2009, I 
> still get confused in *nix when to use a trailing slash and when to not, so 
> this trailing slash worries me, if only for that reason alone.
> 
> I understand.  Here it's to call out that the key references a directory, not 
> a file. The value must explicitly be a directory, not a file, and a trailing 
> slash is the way that is done.  Files are not *required* to have extensions 
> after all.
> 
> Using the `@` here feels cryptic, and hard to discover and remember.
> 
> Perhaps, but this file is meant to be assembled by composer or some other 
> automated means - not by hand.  @ as a package operator is used in Node.js to 
> mark package namespaces - essentially the vendor of the package is marked 
> with @.  

I can tell your design here have been heavily influenced by your stated 
extensive experience with Node.js. Node.js' conventions probably seem second 
nature to you and thus easy for you to understand.

But for those us not steeped in Node.js, they are rather cryptic. Any time 
language designers chooses cryptic over obvious they place a large burden on 
learners and relatedly also on the experienced to deal with, correct and 
educate learners. For the languages targeting larger user bases like PHP — vs, 
say Haskell — the negative impact of cryptic can be widespread and costly in 
time spent and user base lost.  

So even if Node.js made the regrettable decision to choose cryptic over obvious 
I would implore anyone considering additions to PHP to side with obvious over 
cryptic. Even when said additions will often be automated, unless they will 
*always* be automated, such as the OpCache.

What does "obvious" mean here?  Assuming `.ini` files are use, then sections 
names that define usage, not special sigils.

> I think this would be infinitely easier to follow if packages were just 
> included in a `[packages]` section.
> 
> Packages will need to have some special handling though. 

Which does not preclude a special section for [packages].

> If, as Larry Gafield has stated, the engine cannot be made to maintain 
> multiple symbol tables, then the packages must be bound onto the master 
> symbol table.  

I have heard that repeatedly, but I have yet to hear *why*.  

PHP is just a C program, and clearly a C program can have multiple data 
structures.  Linux had a similar problem with filesystems and thus UnionFS was 
created. I'd really like to know why an equivalent architecture cannot be 
achieved with PHP's symbol table.

(If the reason why PHP "cannot be made to maintain multiple symbol tables" has 
been stated already, I could have easily missed it. If so and someone has a 
link to externals.io with the explanation, it would really appreciate that 
link.)

> But the legacy code in the package itself needs to believe it is where it 
> expects to be - on root.  When a Twig file calls to another Twig file it 
> calls `use Twig\Class` in some form or another.
> 
> Monkey patching such as what happens in 
> https://packagist.org/packages/brianhenryie/strauss file accomplishes this in 
> userland by rewriting the files.  The whole of the namespace resolution 
> system is on the fly file renaming, so doing this in the engine should be 
> possible.
> 
>>   ; An import into a package can be done like so
>>   ; Twig will load into \C\Twig and that use will need to be used by any 
>> code outside the C package.
>>   @C\Twig/ = './path/to/Twig/'
> 
> Your comments also confuse me a bit.  
> 
> Is this saying that your hypothetical app — which you stated this `.ini` file 
> is for — needs to use a package named `C` use "definition" is located at 
> './path/to/C/autoload.ini' then it would use this syntax, and that in the app 
> its components would be accessed at namespace `\C`?
> 
> Packages can have an ini file, but they are not REQUIRED to have one. 
> Otherwise, the existing library of packages will not be loadable because they 
> do not have such files.  

Yes, hopefully that would be obvious to everyone.

> Without the @ operator the library wouldn't load correctly because all the 
> files in Twig, parsed normally, will load to \Twig.  The @C\ tells PHP to 
> prefix C to every namespace declaration loaded in that directory and each use 
> statement. This is a new behavior entirely and needs to be carefully 
> considered.

Again, cryptic. 

Certainly there is more than one way to indicate this required behavior besides 
a cryptic sigil.

> I think that would work well for newer libraries and packages authored and 
> used by developers of Developer-managed apps. OTOH I do not think it would be 
> sufficient for any existing libraries or frameworks, nor for non-professional 
> developers scratching their own itch on a User-managed apps and then deciding 
> to publish it for others to use (which happens a lot with User-managed apps.)
> 
> The problem would be that most (all?) of those would not be 
> namespace-prefixing Twig but instead using it directly. I believe you need an 
> ADDITIONAL `replace` sectionS that allowed an app/website developer to 
> indicate that namespace A should instead be replaced in `use` statements and 
> direct references with `B\A` for code that exists in directory(s) `C` but not 
> in directories `C\D` where `C` and `D` can be globs.
>  
> ...
> [replace]
> Twig[UpdraftPlus] = 'Twig_edaf27eb'
> Twig[Elementor] = 'Twig_edaf27eb'
> 
> No, PHP should handle this quietly under the hood without needing the 
> autocomplete author to do this whether it is a person or a userland program 
> like Composer. 

I am pretty sure having PHP "handle it quietly under the hood" could never be 
performant enough for real-world production use on medium-to-high traffic 
websites. That is why I proposed  it be prepared in advance by the actor that 
"builds" the app's source code.  

For developer-managed apps that actor is typically Composer. But for 
user-managed apps that actor is the user-managed app itself, i.e. WordPress and 
the code in its plugin admin page. WordPress would store than info in its MySQL 
database which is why — for others reading this since you already agreed — 
`spl_autoload_map()` would need to be able to get the map as an array vs. as 
just a file.

But I may be wrong. However, one thing is certain; if I am correct that it 
could not be done performantly in PHP then it will never get added to PHP in 
that form, even if an RFC were to pass. So there is really only one way to know 
and that is to develop a proof-of-concept, of which the relevant part here 
could be implement in userland PHP. 

As an side, I have already started piddling with this PoC, but I am not sure 
how far I can or will take it. But I might be open to collaborating on it if 
you are interested.

> Now earlier today I had a thought that shook me.  The entry point of the 
> application in this example will likely call this function before anything 
> else, just as applications like Drupal call the autoload require before 
> anything else.
> 
> So, why not call the map first? then let the map designate the entry point?
> 
> A HUGE Can of opportunity worms opens. This is also a wild tangent, but again 
> this is a brainstorm thread.
> 
>   ; First this autoload map needs to tell PHP what it is.  A Package, or an 
> application.
>   map_type = application

Actually, this seems like a pretty obvious next step once one accepts the idea 
of autoload maps.  

>   ; The Setup files are those which always need to be run before the 
> application is
>   ; ready to do anything.  These files will be loaded with NO ACCESS to 
> globals or
>   ; or super globals. The engine's state after running these files will be op 
> cached and
>   ; each subsequent request starts from here.  This allows the considerable 
> setup work
>   ; that applications like Drupal do to be resolved only once and then start 
> from that
>   ; cache.

Although I like the architecture of having a file define things declaratively 
where they can easily be processed by tooling — I tried and failed to find a 
way to standardize wp-config.php — I am not sure how this would empower the 
OpCache any more than regular code loading from index.php?

> This is also the reason why superglobals aren't visible to these files - the
>   ; state cannot make decisions about any specific request because they'd 
> bleed into
>   ; subsequent requests - a potential security nightmare.
>   ;
>   ; Note the autoloader of this script will be setup in full before these 
> files parse.
>   [setup]
>     [] = 'path/to/first/setup/file.php'
>     [] = 'path/to/second/setup/file.php'

Bikeshedding a bit, I am not sure "setup" is the right word, but as it is 
bikeshedding I will move on.

While I like the idea of a declarative file to empowering tooling, I am not 
sure how introducing such as file into PHP's page load process provides enough 
improvement vs. simply `include()`ing  "setup" php files in the first few lines 
of `index.php`?  I think there would need to be more types of things such a 
file could standardize and improve performance for would need to get buy-in and 
support for such a change. 

To figure that out what those types of things might be would IMO requiring 
looking at widely-used PHP apps — both user and developer managed apps — to see 
what things could see an actual benefit by defining them in a file like this. 
For example, could a database connection be kept alive between page loads on a 
high-traffic site? (I have zero idea if this latter would increase performance 
or even be a good idea, it is just the first thing that came to mind.)

-Mike

Reply via email to