Function getdir() accidentally exists

php.internals

Rowan Collins

5 years ago
Hi all, Following up this Stack Overflow question https://stackoverflow.com/q/66854655/157957 and accompanying bug report https://bugs.php.net/bug.php?id=80914 I have discovered the odd fact that a function was accidentally added to PHP 8.0: getdir() is now an alias for dir() Well, actually, it's slightly weirder than that: dir() is the alias, and getdir() is the real function. It's just that from PHP 4.0 until PHP 7.4, only the alias existed: https://3v4l.org/ZHJ9U In PHP 8.0.x, getdir() is a callable function, and users can't define a function with that name. Here's what seems to have happened: dir() is a function from PHP 3, which is why it creates a weird object with no constructor. Its function entry originally looked like this: {"dir",            php3_getdir,    NULL}, Because the PHP function didn't match the C function name, this got translated to a function *alias* in PHP 4 [1]: PHP_FALIAS(dir, getdir, NULL) But it wasn't really an alias: there was no separate PHP_FE line for "getdir", so "dir" remained the only name you could actually use in PHP code. This situation survived until the move to add arginfo in PHP 8. Maté, quite reasonably, saw that getdir() was missing a stub, and added one. [2] The stubs were then used to re-generate the function entries, and after more than 20 years, getdir() finally got its own function entry:     ZEND_FE(getdir, arginfo_getdir)     ZEND_FALIAS(dir, getdir, arginfo_dir) I've compared the list of PHP_FE / ZEND_FE macros in 7.4 and 8.0, and can't see any others that are obviously wrong, although I noticed that get_mangled_object_vars isn't documented. The obvious question is: should this be considered a bug, and undone, and if so, how? The answer is probably to do what should have been done 20 years ago, and rename the internal definition to match the function name exposed to the user. [1] https://github.com/php/php-src/commit/7a167cd0c1f6ee7c0dce0196b5ca9209a54f534c#diff-a6738c9e7e606e49fc4e7225c281deca86191ada31a5dc077169418541541d1cL59 [2] https://github.com/php/php-src/commit/736b22dc0b2fc36e9bd87f2ee5af8c4b2be9fd3d#diff-96c05a0551ccbeca3ff610c111f88b54a0d727888cf353f477ea8dc951a18637R723
-- Rowan Tommins [IMSoP]

Sara Golemon

5 years ago
On Tue, Apr 6, 2021 at 5:04 PM Rowan Tommins <rowan.collins@gmail.com> wrote:
> Because the PHP function didn't match the C function name, > this got translated to a function *alias* in PHP 4 [1]: >
Curious, since PHP_NAMED_FE *did* exist in this revision that Ze'ev didn't choose to use that macro. Mid 1999 though, so I imagine the development pace going into ZE1 was pretty heavy. Whoopsie!
> The obvious question is: should this be considered a bug, and undone, > and if so, how? > > The answer is probably to do what should have been done 20 years ago, > and rename the internal definition to match the function name exposed to > the user. >
With my 8.0 RM hat on, I say we do that. Call this a bug that the *undocumented* function existed in 8.0.0 through 8.0.3 and remove it. The window of code that will break will be vanishingly small, and if it does impact anyone, the fix is to call dir() instead. Sorted. As to whether or not we deprecate dir()/Directory in 8.x... eh... I'm swiss on that. It's been there for ages and isn't hurting anyone, is it? -Sara

Rowan Collins

5 years ago
On 07/04/2021 00:15, Sara Golemon wrote:
> With my 8.0 RM hat on, I say we do that.  Call this a bug that the > *undocumented* function existed in 8.0.0 through 8.0.3 and remove it.  > The window of code that will break will be vanishingly small, and if > it does impact anyone, the fix is to call dir() instead. Sorted.
Since nobody objected, but nobody seemed to have got round to it yet, I've raised a PR to remove getdir() and rename the internal implementation to dir() once and for all: https://github.com/php/php-src/pull/6855 Regards,
-- Rowan Tommins [IMSoP]