Skip to content

Commit 32d7763

Browse files
committed
move function autoloading to its own branch
1 parent d13508f commit 32d7763

2 files changed

Lines changed: 323 additions & 0 deletions

File tree

drafts/function-autoloading.md

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# PHP RFC: Function Autoloading v4
2+
3+
* Version: 1.0
4+
* Date: 2024-08-15
5+
* Author: Robert Landers, landers.robert@gmail.com
6+
* Status: Under Discussion (or Accepted or Declined)
7+
* First Published at: <http://wiki.php.net/rfc/function_autoloading4>
8+
9+
## Introduction
10+
11+
The topic of supporting function autoloading was brought up many times in the past, this RFC introduces a potential
12+
implementation which would be consistent with what we have for autoloading classes.
13+
14+
## Proposal
15+
16+
Before getting into the details,
17+
there are a few terms worth acknowledging so that the proposal can be easily discussed without getting confused:
18+
19+
1. **Defined function**: A function that the engine has knowledge of, such as in a previously included/required file.
20+
2. **Undefined function**: A function that the engine does not have knowledge of.
21+
3. **Function autoloading**: The process of loading a function that is not defined.
22+
4. **Written function**: A function that exists in a file that the engine may or may not have knowledge of.
23+
5. **Local scope**: The current namespace
24+
6. **Global scope**: The global namespace (`\`)
25+
26+
The suggested change would be pretty straightforward and backwards-compatible:
27+
28+
1. Add two new constants to spl: SPL_AUTOLOAD_CLASS, SPL_AUTOLOAD_FUNCTION.
29+
2. Add a fourth optional parameter for spl_autoload_register, with a default value of SPL_AUTOLOAD_CLASS.
30+
3. The type for the missing token should also be passed to the $autoload_function callback as a second param. (e.g.,
31+
SPL_AUTOLOAD_CLASS for classes, SPL_AUTOLOAD_FUNCTION for functions)
32+
4. Change the current class autoloading to only call the autoloaders which match with the SPL_AUTOLOAD_CLASS types.
33+
5. Add the function autoloading to only call the autoloaders which match with the SPL_AUTOLOAD_FUNCTION types.
34+
35+
There won’t be any changes to the current autoloading mechanism when it comes to classes.
36+
However, if a function
37+
38+
1. is called in a fully qualified form (e.g., a `use` statement or `\` prefix is used),
39+
2. is not defined,
40+
3. and an autoloader is registered with the SPL_AUTOLOAD_FUNCTION type
41+
42+
then the autoloader will be called with the function name as the first parameter (with the initial slash removed) and
43+
SPL_AUTOLOAD_FUNCTION as the second parameter.
44+
45+
However, if a function
46+
47+
1. is called in an unqualified form (e.g., `strlen()`),
48+
2. is not defined locally
49+
3. and an autoloader is registered with the SPL_AUTOLOAD_FUNCTION type
50+
51+
then the autoloader will be called with the current namespace prepended to the function name.
52+
If the autoloader chooses to look up the "basename" of the function, it may do so.
53+
If the function is still undefined in the local scope,
54+
then it will fall back to the global scope—unless the local scope is the global scope.
55+
The function autoloader will not be called again.
56+
57+
This provides an opportunity
58+
for an autoloader to check for the existence of a function in the local scope and define it,
59+
as well as defer to the global scope if it is not defined.
60+
61+
Example "`PSR-4-style`" (except the last part of the namespace is the file it is in) function autoloader:
62+
63+
```php
64+
<?php
65+
66+
spl_autoload_register(function ($function, $type) {
67+
if ($type === SPL_AUTOLOAD_FUNCTION) {
68+
$function_path = dirname(str_replace('\\', DIRECTORY_SEPARATOR, $function));
69+
$file = __DIR__ . '/functions/' . $function_path . '.php';
70+
71+
if (file_exists($file)) {
72+
require_once $file;
73+
}
74+
}
75+
}, false, false, SPL_AUTOLOAD_FUNCTION);
76+
```
77+
78+
Performance-wise, this should have minimal impact on existing codebases as there is no default function autoloader.
79+
80+
For codebases that want to take advantage of function autoloading,
81+
it may be desirable to stick with FQNs for functions and/or employ caches and other techniques where possible.
82+
83+
### spl_autoload
84+
85+
`spl_autoload`'s second argument will be updated to accept `int|string|null` as the second parameter so that it can use
86+
the new callback signature.
87+
If the second parameter is an int, and it is not `SPL_AUTOLOAD_CLASS`,
88+
an `Error` is thrown: 'Default autoloader can only load classes.'
89+
90+
There will not be a default function autoloader.
91+
92+
### spl_autoload_call
93+
94+
The `spl_autoload_call` function will be modified to accept a second parameter of one,
95+
(but not both) of the new constants,
96+
with the default value set to SPL_AUTOLOAD_CLASS.
97+
The name of the first parameter will be changed to `$name` to reflect that it can be a class or function name.
98+
99+
```php
100+
spl_autoload_call('\Some\func', SPL_AUTOLOAD_FUNCTION); // Calls the function autoloader
101+
spl_autoload_call('\Some\func'); // Calls the class autoloader
102+
spl_autoload_call('Some\func', SPL_AUTOLOAD_CLASS); // Calls the class autoloader
103+
spl_autoload_call('Some\func'); // Calls the class autoloader
104+
spl_autoload_call('func', SPL_AUTOLOAD_FUNCTION | SPL_AUTOLOAD_CLASS); // Error: Cannot autoload multiple types
105+
```
106+
107+
If the user wants to call multiple autoloaders, they can do so manually.
108+
109+
### function_exists
110+
111+
The `function_exists` function will be updated to include a boolean option (`$autoload`) as the second parameter,
112+
which will default to `true`.
113+
If set to `true`, the function autoloader will be called if the function is not defined, otherwise, it will not be
114+
called.
115+
116+
## Backward Incompatible Changes
117+
118+
### Mismatched arguments
119+
120+
If an autoloader was registered that can accept more than one argument,
121+
it may fail or perform unexpected behavior when it receives a second argument of `SPL_AUTOLOAD_CLASS`.
122+
123+
## Proposed PHP Version(s)
124+
125+
8.5 or later.
126+
127+
## RFC Impact
128+
129+
### To Opcache
130+
131+
To be determined.
132+
133+
### New Constants
134+
135+
Two new constants will be added to the SPL extension: SPL_AUTOLOAD_CLASS, SPL_AUTOLOAD_FUNCTION.
136+
137+
## Open Issues
138+
139+
To be determined.
140+
141+
## Future Scope
142+
143+
Potentially, constants and stream wrappers can be added in a similar fashion.
144+
145+
## Proposed Voting Choices
146+
147+
<doodle title="Implement Function Autoloading v4, as described" auth="withinboredom" voteType="single" closed="true" closeon="2022-01-01T00:00:00Z">
148+
* Yes
149+
* No
150+
</doodle>
151+
152+
## Patches and Tests
153+
154+
Not yet.
155+
156+
## Implementation
157+
158+
After the project is implemented, this section should contain - the
159+
version(s) it was merged into - a link to the git commit(s) - a link to
160+
the PHP manual entry for the feature - a link to the language
161+
specification section (if any)
162+
163+
## References
164+
165+
- [autofunc](https://wiki.php.net/rfc/autofunc): This heavily influenced this RFC. (declined in 2011)
166+
- [function_autoloading](https://wiki.php.net/rfc/function_autoloading): This RFC was declined in 2011.
167+
- [function_autoloading_v2](https://wiki.php.net/rfc/function_autoloading2): This RFC was declined in 2012.
168+
169+
Thank you for all of those that contributed to the discussions back then. I hope that this RFC will be successful.
170+
171+
## Rejected Features
172+
173+
Keep this updated with features that were discussed on the mail lists.
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
====== PHP RFC: Function Autoloading v4 ======
2+
3+
* Version: 1.0
4+
* Date: 2024-08-15
5+
* Author: Robert Landers, <landers.robert@gmail.com>
6+
* Status: Under Discussion (or Accepted or Declined)
7+
* First Published at: http://wiki.php.net/rfc/function_autoloading4
8+
9+
===== Introduction =====
10+
11+
The topic of supporting function autoloading was brought up many times in the past, this RFC introduces a potential implementation which would be consistent with what we have for autoloading classes.
12+
13+
===== Proposal =====
14+
15+
Before getting into the details, there are a few terms worth acknowledging so that the proposal can be easily discussed without getting confused:
16+
17+
- **Defined function**: A function that the engine has knowledge of, such as in a previously included/required file.
18+
- **Undefined function**: A function that the engine does not have knowledge of.
19+
- **Function autoloading**: The process of loading a function that is not defined.
20+
- **Written function**: A function that exists in a file that the engine may or may not have knowledge of.
21+
- **Local scope**: The current namespace
22+
- **Global scope**: The global namespace (''%%\%%'')
23+
24+
The suggested change would be pretty straightforward and backwards-compatible:
25+
26+
- Add two new constants to spl: SPL_AUTOLOAD_CLASS, SPL_AUTOLOAD_FUNCTION.
27+
- Add a fourth optional parameter for spl_autoload_register, with a default value of SPL_AUTOLOAD_CLASS.
28+
- The type for the missing token should also be passed to the $autoload_function callback as a second param. (e.g., SPL_AUTOLOAD_CLASS for classes, SPL_AUTOLOAD_FUNCTION for functions)
29+
- Change the current class autoloading to only call the autoloaders which match with the SPL_AUTOLOAD_CLASS types.
30+
- Add the function autoloading to only call the autoloaders which match with the SPL_AUTOLOAD_FUNCTION types.
31+
32+
There won’t be any changes to the current autoloading mechanism when it comes to classes. However, if a function
33+
34+
- is called in a fully qualified form (e.g., a ''%%use%%'' statement or ''%%\%%'' prefix is used),
35+
- is not defined,
36+
- and an autoloader is registered with the SPL_AUTOLOAD_FUNCTION type
37+
38+
then the autoloader will be called with the function name as the first parameter (with the initial slash removed) and SPL_AUTOLOAD_FUNCTION as the second parameter.
39+
40+
However, if a function
41+
42+
- is called in an unqualified form (e.g., ''%%strlen()%%''),
43+
- is not defined locally
44+
- and an autoloader is registered with the SPL_AUTOLOAD_FUNCTION type
45+
46+
then the autoloader will be called with the current namespace prepended to the function name. If the autoloader chooses to look up the "basename" of the function, it may do so. If the function is still undefined in the local scope, then it will fall back to the global scope—unless the local scope is the global scope. The function autoloader will not be called again.
47+
48+
This provides an opportunity for an autoloader to check for the existence of a function in the local scope and define it, as well as defer to the global scope if it is not defined.
49+
50+
Example "''%%PSR-4-style%%''" (except the last part of the namespace is the file it is in) function autoloader:
51+
52+
<code php>
53+
<?php
54+
55+
spl_autoload_register(function ($function, $type) {
56+
if ($type === SPL_AUTOLOAD_FUNCTION) {
57+
$function_path = dirname(str_replace('\\', DIRECTORY_SEPARATOR, $function));
58+
$file = __DIR__ . '/functions/' . $function_path . '.php';
59+
60+
if (file_exists($file)) {
61+
require_once $file;
62+
}
63+
}
64+
}, false, false, SPL_AUTOLOAD_FUNCTION);
65+
</code>
66+
67+
Performance-wise, this should have minimal impact on existing codebases as there is no default function autoloader.
68+
69+
For codebases that want to take advantage of function autoloading, it may be desirable to stick with FQNs for functions and/or employ caches and other techniques where possible.
70+
71+
==== spl_autoload ====
72+
73+
''%%spl_autoload%%'''s second argument will be updated to accept ''%%int|string|null%%'' as the second parameter so that it can use the new callback signature. If the second parameter is an int, and it is not ''%%SPL_AUTOLOAD_CLASS%%'', an ''%%Error%%'' is thrown: 'Default autoloader can only load classes.'
74+
75+
There will not be a default function autoloader.
76+
77+
==== spl_autoload_call ====
78+
79+
The ''%%spl_autoload_call%%'' function will be modified to accept a second parameter of one, (but not both) of the new constants, with the default value set to SPL_AUTOLOAD_CLASS. The name of the first parameter will be changed to ''%%$name%%'' to reflect that it can be a class or function name.
80+
81+
<code php>
82+
spl_autoload_call('\Some\func', SPL_AUTOLOAD_FUNCTION); // Calls the function autoloader
83+
spl_autoload_call('\Some\func'); // Calls the class autoloader
84+
spl_autoload_call('Some\func', SPL_AUTOLOAD_CLASS); // Calls the class autoloader
85+
spl_autoload_call('Some\func'); // Calls the class autoloader
86+
spl_autoload_call('func', SPL_AUTOLOAD_FUNCTION | SPL_AUTOLOAD_CLASS); // Error: Cannot autoload multiple types
87+
</code>
88+
89+
If the user wants to call multiple autoloaders, they can do so manually.
90+
91+
==== function_exists ====
92+
93+
The ''%%function_exists%%'' function will be updated to include a boolean option (''%%$autoload%%'') as the second parameter, which will default to ''%%true%%''. If set to ''%%true%%'', the function autoloader will be called if the function is not defined, otherwise, it will not be called.
94+
95+
===== Backward Incompatible Changes =====
96+
97+
==== Mismatched arguments ====
98+
99+
If an autoloader was registered that can accept more than one argument, it may fail or perform unexpected behavior when it receives a second argument of ''%%SPL_AUTOLOAD_CLASS%%''.
100+
101+
===== Proposed PHP Version(s) =====
102+
103+
8.5 or later.
104+
105+
===== RFC Impact =====
106+
107+
==== To Opcache ====
108+
109+
To be determined.
110+
111+
==== New Constants ====
112+
113+
Two new constants will be added to the SPL extension: SPL_AUTOLOAD_CLASS, SPL_AUTOLOAD_FUNCTION.
114+
115+
===== Open Issues =====
116+
117+
To be determined.
118+
119+
===== Future Scope =====
120+
121+
Potentially, constants and stream wrappers can be added in a similar fashion.
122+
123+
===== Proposed Voting Choices =====
124+
125+
126+
<doodle title="Implement Function Autoloading v4, as described" auth="withinboredom" voteType="single" closed="true" closeon="2022-01-01T00:00:00Z">
127+
* Yes
128+
* No
129+
</doodle>
130+
131+
132+
===== Patches and Tests =====
133+
134+
Not yet.
135+
136+
===== Implementation =====
137+
138+
After the project is implemented, this section should contain - the version(s) it was merged into - a link to the git commit(s) - a link to the PHP manual entry for the feature - a link to the language specification section (if any)
139+
140+
===== References =====
141+
142+
* [[https://wiki.php.net/rfc/autofunc|autofunc]]: This heavily influenced this RFC. (declined in 2011)
143+
* [[https://wiki.php.net/rfc/function_autoloading|function_autoloading]]: This RFC was declined in 2011.
144+
* [[https://wiki.php.net/rfc/function_autoloading2|function_autoloading_v2]]: This RFC was declined in 2012.
145+
146+
Thank you for all of those that contributed to the discussions back then. I hope that this RFC will be successful.
147+
148+
===== Rejected Features =====
149+
150+
Keep this updated with features that were discussed on the mail lists.

0 commit comments

Comments
 (0)