Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Replace dot-file with underscore-file
  • Loading branch information
nikic committed Feb 19, 2020
commit e5648065d1147f0f485a793487a1bbe467f8c1d7
6 changes: 3 additions & 3 deletions rfcs/0000-language-evolution.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,13 @@ The advantage of this approach is that it resolves the ambiguities that exist ar

## Filesystem based packages

An alternative to explicit package declarations are filesystem based packages. A package is defined by placing a special file, say `.package.php`, inside a directory, which can then also contain per-package configuration.
An alternative to explicit package declarations are filesystem based packages. A package is defined by placing a special file, say `_package.php`, inside a directory, which can then also contain per-package configuration.

Relative to the previous variant, this has the advantage of not needing an explicit package declaration in every single file. Additionally, unlike both namespace-scoped declares and explicit package declarations, it provides a well-defined place where to look for package-related declares (the `.package.php` file). The previous two variants would place the declares inside `composer.json` by convention, but `namespace_declare()` or `package_declare()` could also be called from other places, which makes tooling support more complicated.
Relative to the previous variant, this has the advantage of not needing an explicit package declaration in every single file. Additionally, unlike both namespace-scoped declares and explicit package declarations, it provides a well-defined place where to look for package-related declares (the `_package.php` file). The previous two variants would place the declares inside `composer.json` by convention, but `namespace_declare()` or `package_declare()` could also be called from other places, which makes tooling support more complicated.

The disadvantage of this approach is the filesystem coupling, which introduces a number of problems in PHP:

* Cache invalidation: Within one request, PHP would presumably cache both which directories do not contain a `.package.php` file, and the contents of the ones which do. Changes to either of those would be ignored during the request. The more problematic case is how these would interact with opcache. If `validate_timestamps` is enabled, we would have to check all the directories (and parent directories) for added, removed or changed `.package.php` files as well, which may carry an additional performance penalty.
* Cache invalidation: Within one request, PHP would presumably cache both which directories do not contain a `_package.php` file, and the contents of the ones which do. Changes to either of those would be ignored during the request. The more problematic case is how these would interact with opcache. If `validate_timestamps` is enabled, we would have to check all the directories (and parent directories) for added, removed or changed `_package.php` files as well, which may carry an additional performance penalty.
* Path canonicalization: In order to determine whether a file is part of a package, canonicalized paths need to be available. For example, symlinks must be resolved, and case-(in)sensitivity of the filesystem must be handled correctly. While this functionality is available on the filesystem layer through `realpath()`, this functionality currently does not exist for general PHP streams (not even phars support this properly). This may be solvable with additional stream wrapper hooks.
* Directory traversal: In order to find package files, we need to go "upwards" in a given path to find package files. Once again this operation is not supported by stream wrappers. In fact, many stream wrappers do not have a meaningful concept of a "directory".
* Generally, it may be hard to make this feature work with arbitrary streams. I have a package that replaces the `file` stream wrapper, in order to intercept all included files and replace them with preprocessed files stored in a temporary directory. I have no idea just how this would interact with a directory-based package system.
Expand Down