Hi Rowan, wt., 13 sie 2019 o 22:26 Rowan Collins <rowan.coll...@gmail.com> napisał(a):
> On 13/08/2019 18:45, Mark Randall wrote: > > I thought about this as my first consideration, however it effectively > > requires that the PHP code within the package class is fully parsed > > and executed in order for it to retrieve the data. > > > > Consider pre-loading where the code is compiled, but not run, it would > > not be possible to use namespace level defines to add compile-level > > optimizations or checks (at least without some AST hackery). > > > Ah, that makes sense. Does that necessarily mean we need a dummy class, > though? The autoloading logic in the engine knows that it called the > autoload callback expecting a package definition, so can count as > success that the package is now defined. > > In other words, the file the autoloader included would look like this > (again, sticking to the notion that "package" is separate from > "namespace"): > > > # > # File: /lib/company/project1.php > # > > <?php > > packagedef company/project1 { > strict_types=1; > strict_operators=1; > upgrade_errors_to_exceptions=E_ALL; > } > Was thinking a while about proper syntax and would like to mention what I said before. It doesn't have to be a new syntax if we agree to put package definiction in sort of separate configuration file. In the end all what we need is package name and a bunch of declare directives. Given that it could be easily done using separate conf file like: # package.ini [package] name = MyVendor\MyLibrary strict_types = 1 encoding = UTF-8 # package.json { "name": "MyVendor\\MyLibrary", "declare": { "strict_types": 1, "encoding": "UTF-8" } } # package.toml [[package]] name = "MyVendor\\MyLibrary" strict_types = 1 encoding = "UTF-8" # package.yaml name: MyVendor\MyLibrary strict_types: 1 encoding: UTF-8 That way it would prevent to mix normal PHP code with package definition, cause every possible PHP syntax we would agree, opens the door to add something more to that file, for eg.: # package.php <?php declare package MyVendor\MyLibrary { strict_types = 1, encoding = "UTF-8" } function foo() {} In this early package design stage, all what we need and what was the motivation of Nikita RFC[1] which was to provide a solution for package/namespace scoped declare directives - nothing more. Thus with the configuration file, it would be easier to add more directives and deprecate them / ignore additional settings. I was thinking over the current state with valid directives, which now are: strict_types, ticks and encoding. Although I don't use ticks and encoding, both works in very narrow cases and could be cleaned up. * encoding - seems to work only if PHP was compiled with additional configure flag mostly as I suspect in whole project/library/package rather than a single file; * ticks - this is only for declaring the ticks=N - the number of ticks which without register_tick_function[2] so the N argument probably could be even moved as a parameter while registering tick function BTW: official examples show the second parameter as true but there is no description on what does it affect Going further IMO it would make sense only to adopt encoding as a proper package declaration with strict_types directive. I'd like to refer to the package name as part of FQCN. If that would be a part of FQCN like for eg: <?php use MyVendor\MyLibrary:FooBar\Baz; Then it would be possible to extract it and load package definition before class autoload would attempt to load source file and meet: <?php package MyVendor\MyLibrary; namespace FooBar; class Baz {} In a future, a separate configuration file can be easily used for preloading (by glob mask) or bootstrapping, for eg. (no matter of agreed format): # package.ini [package] name = MyVendor\MyLibrary preload = src/**/*.php bootstrap = src/functions.php Or even defining editions, like: # package.ini [package] name = MyVendor\MyLibrary edition = 2020 Concluding I can see more benefits adopting separate configuration file than drawbacks in oppose to PHP file: Benefits: * hard to write syntax error * impossible to inject user code and avoid circular dependencies, when file /lib/company/project1.php declares or uses other symbols from a different package which would require loading machinery to load it and cycle own usage * doesn't add PHP parser complexity * easy to ignore abandoned attributes * together with package name part of FQCN loaded before any package source code parsing (well here is something missing when trying to directly execute a file with package scoped class and it's usage) * not possible to dynamically create the package definition * good place to provide an edition (if ever such an approach would be adopted) - which could be by design a set of strict declare directives without the need to specify each strict_* directive separately Drawbacks: * need for new loading machinery * not possible to dynamically create the package definition (this could be an argument for and against depends on needs) P.S. Maybe I'm repeating myself, then I'm sorry. I just got an impression that wasn't heard enough. Please comment your thoughts on that. [1] https://wiki.php.net/rfc/namespace_scoped_declares#motivation_and_vision [2] https://www.php.net/manual/en/function.register-tick-function.php -- regards / pozdrawiam, -- Michał Brzuchalski about.me/brzuchal brzuchalski.com