まとめ
PHP8.0.0からPHP8.0.3までの間、getdir()という組み込み関数が存在する。
Stack Overflow
PHP 8, function alias compatibility getdir()
こんなコードを書いたらなんかPHP8でエラーになるんだけど。
function getDir($a, $o = 2) {
$d = Floor($a / $o);
return ($d % 2 === 0);
}
んで調べてみたらgetdirはdirのエイリアスになってるみたい。
リリースノートにもエイリアスのこと全く書かれてないんだけど、なにこれ?
Answer 2
getdirはPHP4時代の非常に古い関数なんだけど、最近仕様が変わったりしたのかね?
Answer 4
バグレポ出したよ。
getdirはケースセンシティブだったのがケースインセンシティブになったせいかね?
Answer 5
↑ちょっと待った、ケースセンシティブは関係ないんだ。
getdir()関数はこれまでずっと存在していなかったんだ。
でもソース中にはずっと存在していたんだ。
何か深刻なことが起こっているにちがいないぞ。
PHPメーリングリスト
Rowan Tommins
Stack Overflowの質問https://stackoverflow.com/q/66854655/157957およびそれに伴うバグレポートhttps://bugs.php.net/bug.php?id=80914において、不可解な現象が発生しました。
PHP8.0において、dir()関数の別名としてgetdir()が誤って追加されました。
実際はもっと奇妙なことになっています。
本当はgetdir()が正しい関数名で、dir()はそのエイリアスです。
しかし、PHP7.4まではエイリアスの方の関数しか存在しませんでした。
PHP8.0においてはgetdir()は呼び出し可能な関数であり、そしてユーザが同名の関数を定義することはできません。
これは以下が原因だと思われます。
まず、dir()はPHP3から存在する関数であり、それはコンストラクタを使わないおかしなオブジェクトを生成します。
{"dir", php3_getdir, NULL},
PHPの関数名がCの関数名と一致しないため、PHP4のエイリアス機能によって以下に置き換えられます。
PHP_FALIAS(dir, getdir, NULL)
しかし、これは実際にはエイリアスではありませんでした。
PHP_FEマクロにgetdirが登録されていなかったためです。
そのため、コードで実際に使用できる関数名はdirだけでした。
この状況は、PHP8でarginfoが追加されるまで続きました。
Matéはgetdir()にスタブが無いことに気が付き、それを追加してくれました。
そして20年の時を経て、ついにgetdir()に関数エントリが追加されたのです。
ZEND_FE(getdir, arginfo_getdir)
ZEND_FALIAS(dir, getdir, arginfo_dir)
問題は、これをバグとみなして元に戻すべきかということです。
答え合わせはおそらく20年前に行われるべきだったもので、公開されている関数名に合わせて内部名を変更すべきでしょう。
Sara Golemon
PHP_NAMED_FEってマクロは当時も存在してたのに、Zeevはどうしてそのマクロを使わなかったのでしょう。
1999年当時はZend Engine1の開発真っ最中だったからてんやわんやだったのかな。
私なら、この文書化されていない関数は、PHP8.0.0から8.0.3までに存在していたバグとして葬ります。
Rowan Tommins
異議はなかったので、プルリクエストを提出しました。
getdir()を削除し、dir()関数の内部名をdirにします。
感想
C素人なのでPHPのソース読むのつらい。
PHPの関数は、まず関数を定義して、その情報を別途インデックスに登録することで使用可能になります。
getdir()関数は、定義自体はずっと前から存在し、むしろdir()がgetdir()へのエイリアスという構造でした。
しかし、getdir()関数はインデックスに登録されていなかったので使えない状態でした。
PHP8実装に伴い気を利かせてソースを整理したら、その前世紀の遺物が意図せず現出してきたということです。
閉ざされていた古代遺跡が復活した感ありますね。
↧