Hi Michael, On Wed, Jun 26, 2024 at 11:21 PM Michael Morris <tendo...@gmail.com> wrote:
> Hello all. This is a ramble of an idea that's managed to run around my > head for a few days now. It isn't fully formed, but I've ran the thought > experiment as far as I can on my own and want to share it with all of you. > > I've mostly been a lurker and I've seen a lot of RFC's come and go. Of > those not accepted many have been passed over because of background > compatibility. And then there is the issue that PHP has multiple design > flaws that seem impossible to get rid of. Finally, I sense from > conversations I've read that there are a lot of engine parser optimizations > that haven't been tried because of the background compatibility problems > present. > > JavaScript was in this position as well 10 years ago when JavaScript > modules were introduced with the ES6 syntax. Only recently have these > modules finally begun to become first class members of node.js. The > existing CommonJS require mechanism remains and will remain in Node for the > foreseeable future, but the ES6 syntax allows an opportunity to sidestep > the issue. The most significant of these is JavaScript modules run in > strict mode, which actually removes features that are problematic for the > engine or make it difficult to create optimized code. > Working with Typescript a little bit does give a vibe that PHP could borrow some of the concepts there and be improved greatly and I share this sentiment. > Something similar could be done in PHP, and that's what the remainder of > this letter is about, but before I continue I want to make clear my vantage > point: I am but a humble user of the code, I'm no expert on the > underpinnings of the Zend engine. In the text to follow I'm going to make > wrong calls on some things - maybe multiple things. I'm not married to > anything here. Further, even if I were a master of the engine and knew > where to start, the scope of this is too large for any one person to > undertake. > Who would build it is an extremely key aspect of making changes to PHP. Ideas are hard enough to survive the RFC process when there's already an implementation. Finding a sponsor to work on this would be the first step. > So all that said, I'll begin. > > PHP User Modules are php files that are brought into the runtime through a > new parser that is able to generate faster and more concise runtime code by > removing support for problematic features and imposing a strict mode by > default. They focus on PHP as a language and not as a template engine. > > The only background compatibility break is the introduction of three > keywords: "import", "export" and "from" > > The PHP interpreter does not load PHP files as modules unless it is > directed to do so in an ini file or an .htaccess file using the > default_filetype directive. If this directive is missing its value will be > "default" - the value "module" will be used to trigger loading the initial > PHP file as a module, and further types could in theory be introduced at a > far later date. > > Again, this setting only affects the INITIAL PHP script file loaded by the > interpreter, such as the index.php of Drupal. Files that are included with > include, include_once, require, or require_once will be imported as they > always have. Files that are included with import are PHP User Modules. > Given that ini settings are frowned upon nowadays, I think having a `<?php declare(modules=1);` for the initial file might make the idea more likely to pass a vote? Or maybe I'd even try to go one step further and say that whatever file is being executed by SAPI (the first PHP file) could be interpreted with a dumb lookahead. If the file has import / export syntax, treat it like PHP Module, otherwise fallback. The fun really starts when the from clause shows up. > > ``` > import foo from "foo.php" > ``` > > The search order of import is as follows: > 1. Is the file in the same directory as the importing file? Yes, load. > 2. Is there a php_modules directory? If so, is the file in there? > 3. If the importing file is within the tree of the cwd (established by the > first file loaded), then recursively look for a php_modules directory until > at the cwd until the file is found (this is identical to the seek process > of node with it's analogous node_modules directory > 4. As a final try, consider the PHP include_paths. > I'm not familiar enough with Javascript / Typescript ecosystem, but I've only ever seen / used the ability to import using direct filepath. The fact there's weird behaviors as result of trying to import a file and suddenly a file all the way from `include_paths` or `php_modules` seems like a no-go to me. I'd favor using only simple file path navigation and if the file doesn't exist, error. Perhaps if the idea gains merit, Composer could offer something similar to Vite where we can create an alias to a specific folder and then import things like `from '@package/path/to/file`. > This will of course require a package manager similar to composer to > become part of core. However, composer will not be eclipsed as the import > package manager (phppm?) is only concerned with user modules. These modules > must explicitly export any symbols being fetched from them, whereas > composer will continue to load files using require. > > Imports can also be done against directories > > ``` > import foo from "mypackage" > ``` > > In this case the parser will look for "mypackage/index.php" > I'm not fond of this either. ---------------- Overall, I think PHP has already reached the limit of surviving with only PSR-4 and Composer. Single class files were a great solution to get us out of the nightmare of `require` and `import` on top of PHP files. But more than once I have had the desire to declare a couple of interfaces in a single file, or a handful of Enums, etc. It seems like PHP Modules could also address the issue with function autoloading and package-level visibility. I like the idea but I'm a bit skeptical until we have some buy-in from someone that could actually get this implemented. -- Marco Deleu