PHP RFC: Should PHP have a directive that makes the parser treat all namespaced function calls as global?
- Version: 0.9
- Date: 2024-08-04
- Author: Nick Lockheart, lists@ageofdream.com
- Status: Under Discussion
- First Published at: https://wiki.php.net/rfc/global_function_parser_directive
Backward Incompatible Changes
No backwards incompatibility.
Proposed PHP Version(s)
Proposed for next PHP 8.x or 9.
Introduction
When calling functions from the global namespace, the PHP parser creates opcodes that use those functions directly. When those functions are certain built-in functions, the parser can use special opcodes that are optimized for those function calls.
When calling functions from within a namespace, the parser does not know at compile time if the function is defined in the current namespace or if the global function will be used.
Because unqualified function calls are ambiguous, the parser adds an NS Lookup opcode which performs a runtime check for the function name in the current namespace, and then falls back to the global namespace if the function is not defined locally.
This also prevents the parser from using dedicated opcodes for built-in functions.
As a result, some estimate that using namespaces in PHP incurs a 3-5% performance penalty.
Workaround
There is a workaround to this problem.
If every function call is preceded by a namespace or by a backslash (for the global namespace), the parser can determine if the function is local or global at compile time.
This eliminates the performance penalty, but causes all namespaced code to be filled with backslashes for built-in functions.
Use Cases
There are many projects that don't need functions in the local namespace.
There is also a legitimate need to allow namespaced functions to override global functions, including overriding certain built-in functions.
For example, a developer may wish to override the fopen
, fwrite
, and similar functions with mocks for unit testing.
Proposal
The current and default behavior of PHP is to create an NS Lookup opcode for ambiguous function calls. (Ambiguous meaning that the namespace is not fully qualified).
Over the past four or more years, various people have proposed different ways of changing the default parser behavior, with the goal of allowing developers to override this default behavior by telling the parser to resolve all ambiguous functions as if they were global.
(A counterpoint would be a similar directive to resolve all ambiguous functions as if they were local, and disable the global fallback to avoid the NS Lookup overhead.)
The general gist of all of the various proposals made over the years was that there should be some way to clearly signal to the parser that all unqualified functions should be treated as global, without the need to put a backslash in front of every single function call.
When this proposed directive is present, the parser will act as if all unqualified function names have a backslash, and the parser will use the global functions without an NS Lookup at runtime. Further, the parser would use the dedicated opcodes for built-in functions.
Scope
In the past, RFCs that aimed to address this issue got too hung up on a syntax discussion, rather than a simple “should we solve this” question proposed to the community.
I would like to discuss and then vote on this proposal as a feature, without getting into any specifics of syntax.
I propose that we vote yes/no on if there should be some way, whatever that way ends up being, to tell the parser to always treat unqualified function names as global.
I think it's important to get a “clean vote” on this issue, to separate out if past objections were objections to the concept, or if only the syntax proposed in past discussions was disfavored.
Proposed Question
I am asking that we discuss and vote on the following question:
“Should there be some way for developers to signal to the parser at compile time that all unqualified function names found in a namespace context are global, without a namespace lookup?”
Yes: We should do this, let's discuss syntax possibilities.
No: This should not be a feature at all.
Implementation
If this RFC is approved, it will be implemented by creating a new RFC to discuss and then vote on syntax.
Unaffected PHP Functionality
This proposal will have no effect on class names.
This proposal will have no effect on class methods.
This proposal will have no effect on fully-qualified function calls.
References
Will be updated with links to external references, discussions or RFCs as needed.
Discussion
Will be updated with features that are discussed on the mail lists.