This turned out to be a lot more interesting than I expected.
The short answer is that getdir() really is new in PHP 8.0.0, but this was a mistake, and it will probably be removed in 8.0.4 or 8.0.5.
The interesting part is that getdir() is not in fact an alias, but the real name of the function internally; it's just that until 8.0, it was only accessible via its alias, dir(). To explain that, we have to go back more than 20 years...
The dir() function was added in PHP 3.0. For whatever reason - perhaps a last-minute change of name - the C function that implemented it was called "php3_getdir" not "php3_dir". That didn't matter, because every function name was mapped explicitly, like this:
function_entry php3_dir_functions[] = {
{"opendir", php3_opendir, NULL},
{"closedir", php3_closedir, NULL},
{"chdir", php3_chdir, NULL},
{"rewinddir", php3_rewinddir, NULL},
{"readdir", php3_readdir, NULL},
{"dir", php3_getdir, NULL},
{NULL, NULL, NULL}
};
Not long after, PHP 4 came along, and function definitions moved to using macros to match the C name to the PHP name. Since the name of the function and implementation didn't match, "dir" ended up labelled as an "alias"; but no extra entry was added for "getdir":
static zend_function_entry php_dir_functions[] = {
PHP_FE(opendir, NULL)
PHP_FE(closedir, NULL)
PHP_FE(chdir, NULL)
PHP_FE(rewinddir, NULL)
PHP_FE(readdir, NULL)
PHP_FALIAS(dir, getdir, NULL)
{NULL, NULL, NULL}
};
An alias without a target doesn't really make sense (and there was a PHP_NAMED_FE macro for just this purpose) but it worked, so I guess nobody noticed.
In fact, through all the changes of PHP 5 and PHP 7, it carried on working, with basically the same line of C code right up to 7.4.
PHP_FALIAS(dir, getdir, arginfo_dir)
During the work on PHP 8, however, a system was built to generate internal function information from PHP "stubs". As part of this stubs were added for all function aliases, and getdir() ended up with its own stub:
/** @param resource $context */
function getdir(string $directory, $context = null): Directory|false {}
/**
* @param resource|null $context
* @alias getdir
*/
function dir(string $directory, $context = null): Directory|false {}
This was then used to re-generate the C definitions, and finally getdir() had its own function entry
ZEND_FE(getdir, arginfo_getdir)
ZEND_FALIAS(dir, getdir, arginfo_dir)
This caused getdir() to be a real built-in function name, and meant you couldn't have a function with the same name.
From there, four things have happened:
- 29th March 2021: 0stone0 posted this question.
- Chris Haas tried to hunt down the issue, and opened a bug on the PHP bug tracker, thinking that the issue related to case sensitivity. They also confirmed that getdir() was the only alias in basic_functions.stub.php not in the manual.
- 6th April 2021: Thinking I was going to make a quick documentation fix, I got interested, and disappeared down the above rabbit hole. I posted my findings to the PHP internals mailing list and went to bed an hour later than I intended.
- Sara Golemon (one of the PHP 8.0 Release Managers) replied agreeing that it should be treated as a bug and reverted in the next 8.0.x release. She also posted an answer here since I hadn't yet.