On Mon, Jun 15, 2026 at 5:45 AM Alex Rock <[email protected]> wrote:
> Le 13/06/2026 à 19:14, Rowan Tommins [IMSoP] a écrit : > > On 13 June 2026 16:32:08 BST, Michael Morris <[email protected]> wrote: > > > >> Namespaces in PHP are a bit of a hack - they prepend the stated > namespace > >> to all labels declared in the file, and the use statement allows the > fully > >> qualified name of a class, function or constant to be stated only once, > >> usually at the head of the file. It also allows aliasing, say if you > have a > >> "Parser" class out of two different packages - you can alias them as > >> "FooParser" and "BarParser". It looks like Java or JavaScript importing, > >> but it isn't. > > A small correction: this is exactly the same way that namespaces work in > Java, with exactly the same implication: the fully qualified class name has > to be globally unique. Java's solution to isolating an entire set of names > is apparently to define an "Isolated ClassLoader": > https://www.javathinking.com/blog/what-is-an-isolated-classloader-in-java/ > > > > C# also has this model of namespaces, but allows you to isolate a set of > names from a particular "assembly" using an "extern alias" statement: > https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/extern-alias > > > > I suspect both mechanisms rely on details of their respective runtimes > that wouldn't translate to PHP, but in principle what we're looking for is > something similar. > > > > > > > > Rowan Tommins > > [IMSoP] > > > Namespaces being just a globally accessible and define-able symbols > system is exactly why, so far, a PHP package cannot define "private > internal" code. The way the language works already allows > autoload-hijacking in order to override code from external libs, or even > hack the visibility (like removing "final" or "private" keywords before > autoloading the file...). > PHP has never kept people from shooting themselves in the foot. And in the past it's came with some big guns too (Register Globals in PHP 3 anyone?). Enforcing namespace visibility will come at a cost in performance, and it won't be enough to stop people from shooting themselves because PHP code is quite mutable. I don't see much of a point in trying to guide people's coding, especially in a language that doesn't have a set paradigm. That is, in Java, you're using classes. In PHP you can approach things that way, but you write purely procedurally. You can use the language as it was originally conceived - a templating language. > After 18 years of PHP coding, including 15 years as a professional, I've > seen a huge lot of legacy PHP projects that benefit the language's > flexibility. Sure thing many of businesses could succeed thanks to being > able to override almost everything (contrary to stricter languages), but > maintaining these codebases with up-to-date versions of PHP, or > 3rd-party libs, is so much of a hassle that, at some point, lots of > maintainers are going more and more into adding new things into PHP that > enforce a bit more strictness, opt-in of course. Some other libs (I'm > thinking about EasyAdmin, in the Symfony ecosystem, for example) have > even made the choice to close pretty much everything and provide > "maintainable" public entrypoints, enforcing the Open/Close principle > with a strict approach (immutable final classes, stricter options and > arguments, etc.). It has its pros and cons, and can be frustrating for > some devs, but the main goal was to make maintenance a bit easier for > the core devs so that they are not forced to maintain BC on too many > layers. > Introducing Modules, whether they are based on namespaces or not, would > help maintainers, I think, and could reinvent how we think of PHP > packages, while still keeping PHP what it has always been because it > would be opt-in for maintainers. > When you say modules, what are talking about, because multiple languages implement "modules" in different ways. JavaScript is the most well known, but Go also has modules and they are quite different and support versioning out of the box. In each of these examples there is a requirement that the programmer write code to import the modules at some place either in the project (Go) or in every bloody file in the project (JavaScript). PHP doesn't require this, instead autoloading symbol definitions as they are encountered. Any package/module/whatchamacallit system used in PHP needs to build on this principle, not swim against it, if it is to have any hope of consideration on the list. Also, I think the following is important to point out - Composer is NOT a package manager. It is a dependency manager. There's a subtle difference between the two. > > On my side, I don't care if modules are tightly coupled to namespaces or > not, and if more, that's even why my first idea was to bind a module to > a single-file at first, and making all modules imported from such file > being non-importable-again, thus creating a single module tree that can > be stored at compile-time, have no side-effect at load-time (which is a > big safeguard to avoid other issues), and allowing multiple modules of > seemingly same name to be loaded in the memory at the same time, > similarly to how Node.js allows having different versions of the same > packages to be installed, while also allowing to have one version used > by many modules too. > NPM (not Node, node is the engine not the package/dependency manager) does this using aliases. PHP doesn't have a way to alias symbols at compile time. It would be nice if it did - I've suggested it as a parameter to include not knowing at the time of the suggestion that include isn't a function, it's a statement, so `include "file.php"` is the same as `include("file.php")`. Setting that aside, PHP projects rarely execute the include themselves - they let an autoloader handle it, so the autoloader must know which version to load. This isn't something that even NPM does - it just aliases and makes both libraries available. The caller still must specify which library is being pulled in. Node modules have a single point of entry, defined in the package.json file but usually index.js. In most Node packages this index.js imports all the public parts of the package and immediately exports them. Further, an import in node is an object (as is everything in JavaScript) that corresponds to that file. Hence import { foo, bar } from 'MyPackage'; This is using JavaScripts dereference mechanic to pluck members of an object into the current symbol table. I could go on, but I think it's more on topic to just say that Node's import/export mechanic, elegant as it looks, is highly bound to JavaScript's scope rules and how its symbol table works. These aren't compatible with PHP. For one, PHP has two symbol tables - one for variables (which is why all variables start with $ ) and one for everything else. Variables are affected by function scope, nothing else is. For example, if you define a function within a function in JavaScript that function will be private to the function it is defined in - it can't be seen in other scopes. In PHP the function will be visible on the symbol table. For another, Node gives each file its own module scope. To move a symbol from one file to another you should use export and import. This creates a clear chain of custody for objects and symbols, but by God it also creates a LOT of boilerplate that the PHP community has no interest in replicating. Without the chain of custody you rapidly run into trouble. It doesn't matter if you try to allow the user to put a prefix on the namespace as I once suggested, or have PHP's engine prefix it automagically somehow - you still need to correctly disambiguate every blasted reference to that namespace. This is no easy task - take a look at the code of Strauss - https://github.com/BrianHenryIE/strauss That project allows you to rewrite a package with a new namespace, in effect doing it in userland. But as a precaution it prefixes every single package imported and severs the tie back to the original packagist. Strauss is used by several WordPress plugins to make composer library use possible while still remaining portable between WordPress sites. > The only drawback of having modules like that would be that final > dependency trees in Composer would be non-flat, but again, I think this > non-flat system should be opt-in. Similarly to how flat systems are > opt-in in the Node.js ecosystem (and trust me, I've tried to enforce > "flat" dependencies resolutions in certain Node projects, and it's a > huge hassle). Luckily, the PHP ecosystem is quite fine so far, compared > to Node, and I would definitely keep the "flat" system in Composer for > as long as possible, and make non-flat resolutions only case-specific > (which is rare, and usually framework-dependent, like with Wordpress > plugins for instance). > I don't think it's a reasonable ask of Composer or any other dependency manager to try to resolve this without having a clear binding map like the one JavaScript forces you to create by how its module system works. > > I still hope we could have a grouped discussion on this. > > Larry's Modules proposal (here: > https://github.com/Crell/php-rfcs/blob/master/modules/spec-brainstorm.md ) > > is IMO a very good starting point, and it only lacks the "multiple > modules with different versions". And module definition with an INI file > looks interesting. > > Adding a "container" system when importing a module can maybe allow > this, I don't know...? > > @Michael: do you think you could start a new thread for PHP containers? > Do you already have some research that you could bring for a pre-RFC > discussion? > This is the Container thread - I changed the subject line on my previous reply although I did include (was: ) so that people could track I was forking. I don't have much to add beyond my previous post. I haven't heard from anyone with engine experience about the feasibility or difficulty of what I propose. To review (for anyone just joining but missing the previous message) 1. The user signals to the engine they want to include a php file AND process it independent of the current execution environment. No shared user defined symbols or variables. 2. That file returns an interface so that the calling thread can talk to the child. 3. As the processes reside on different threads these calls will need to be asynchronous to be optimal, otherwise the caller will be in a blocked state while the child executes the called method. It can work without the PHP Async / Await RFC's conclusion, but it won't be in ideal form without it. Containers provide process isolation. Say I have a WordPress plugin that I want to use composer libraries with. Say, Guzzle. I can write my own container interface without touching Guzzle's code exposing the parts of Guzzle I need for my plugin. Since WordPress has no current core composer support I would need to carry a loader in my distro to be ran on the install hook of the plugin, bringing in composer and letting it in turn pull the libraries that I need to use. If someone later writes a plugin that uses an incompatible version of Guzzle that doesn't matter - even if they lazily load it into the main symbol table by not using a container. My plugin is isolated. That isolation comes at a price. Each plugin has an independent vendor directory with no way to resolve complete redundancy. At least not in WordPress, which has no current composer implementation in core (I'm on the wp trac in a thread discussing it though). There are open questions though that must be answered before this container idea is seriously explored. Most critical, can PHP be made to handle an object passing from one thread to another? That is, continuing from the example above, can a client instance from one GuzzleContainer coexist on the main thread with a client instance from a different container and referencing different code? Or will methods be unable to cross the barrier? What are the implications for the Reflection API and using it to examine an object that originated from another process thread referencing symbols that don't exist on the current thread? The idea of containers is simple to state - but the implications are profound and might be unworkable. I simply don't know enough about the PHP engine to know.
