今週の PHP 2022/12/10 〜 2022/12/16
PHP のメーリングリストから、気になった情報をピックアップします。
Internal
Revisiting RFC: Engine Warnings -- Undefined array index - Externals
PHP 8.0 の互換性のない変更リストにも書いてありますが、未定義の配列キーを読み取ろうとした場合に、警告 E_WARNING
になります。
7.4 までは、E_NOTICE
だったものです。
上記変更に関わる RFC はこちら -> https://wiki.php.net/rfc/engine_warnings
このおかげで、$arr['key']
という記述は isset($arr) && isset($arr['key']) && $arr['key']
という風に長ったらしく書かなければいけなくなってしまった。
20年も E_NOTICE
にしてたのにひどいよ。なので、未定義の配列キーに対するエラーレベルを設定可能にしてくれないか?というご意見
これに対しては
- 20年はそうだったかもしれないけど、直近3年は違うよ。
- 移行期間は 2+1 年用意されていた。
- E_WARNING になるだけで、振る舞いには変更がない。
- この変更が覆ることはまず考えられない。
という、非常にもっともな意見が返されました。
PHP は、開発者が正しく開発できるようにする方向に向かっているから、この変化に追随しようよ。という意見や、実際に Undefined Index の状態と、それ以外に対するベンチマークを取ってくれた人もいました。
言語的にも、Undefined Index が存在しないほうが、高速に動作します。Null 合体演算子の利用でも同様に高速動作しています。
すこし面白かったのは、Ubuntu 20.04 などで、パッケージ版の PHP を利用している方にとっては、PHP 7.4 はかなり身近な存在で、8.0 系にようやく乗り換えようというタイミングが今になっているという話でした。
手元の Ubuntu 22.04 LTS (Jammy) で確認しましたが、入れようと思えば、まだ PHP 7.4 を入れられそうでした。本当に 8.0 系大移動はこれからなのかもしれないですね。
話は、結構膨らんで
-
undefined
っていう新しい primitive を返すようにしよう - Null 合体演算子は名前がおかしい
などなど、関係ない方向にも飛び火していきました。
Remove PHP-x.y.* git branches - Externals
下記のイシュー主からのお便り
Remove PHP-x.y.* git branches · Issue #10007 · php/php-src
要するに、一般的でなかったり、古かったりするブランチは削除しませんか?という話です。
具体的には
a) PHP-x-y-*
のブランチ
internal
のメール文面は多分あやまりで PHP-x.y.*
と思われます。
例えばこれ -> https://github.com/php/php-src/tree/PHP-7.1.0RC3
過去を遡ると、かなり前のバージョンまで全部入っています。
b) 10年以上前のブランチ
めちゃくちゃ古いやつで、反映されてない変更はローカロのSVNから復帰させて、新しいプッシュすればいいよね?
そんなものがあればの話だが... という雰囲気
これに対する意見としては
- リリースプロセスと結びついているので、修正するならリリースプロセスも直さないとだめ
- Tag でバージョンは表現されているから、ブランチが不要なのはわかるけど、別に消さなくてもいいんじゃ?
- バージョンをGUIのセレクターで選ぶときに、バージョンが多すぎて辛い
- 確かに semver には沿ってないけど、コミュニティにいる人はすぐに慣れるのでは
- PHP のリリースプロセスにおいて、分かりやすい名前の バージョンブランチがいることは良いと思う
などなど、消してもいいとは思うが、既存でも十分に回っているという感じの意見が多かったです。
リリースプロセスにも関わる話なので、RFC を整えるだけでも結構大変そうですね。
Bugs
Fix bug #79836: Segfault in concat_function by nielsdos · Pull Request #10049 · php/php-src
下記のようなコードで、SegV が出るというイシュー。現在も修正中ですが、原因はメモリーリークだったようです。
ob_start ( function () use ( & $c ) { $c = 0 ;}, 1 );
$c .= [];
$c .= [];
FTBFS PHP 8.2 on Ubuntu 18.04 ppc64el · Issue #10077 · php/php-src
ppc64el ってなにかなと思ったら、Little-Endian でした。
こちらが修正パッチ
すでに解決済みです。
main/php_ini.c: remove dead code by glensc · Pull Request #4512 · php/php-src
Merge されるまでに3年4ヶ月かかったそうです。php_ini 関連の重複コード改善。
PHP 8.0+ does no longer accept a comment in the whitespace between ampersand and argument in function signature · Issue #10083 · php/php-src
引数内の & と 引数の間にコメントが書けなくなっているというイシュー
実際に試してみると、8.1 系からはコンパイルに失敗します。これは、交差型の導入によりパースに変更が入ったためということです。
というわけで won't fix
のタグが入ったのですが、Lexer の正規表現を工夫したらイケるかもということで re-open されています。
&
の後方にあるホワイトスペースとコメントを認識するという形に変更されています。
これが取り入れられると、コメントがまた書けるようになります。
もとのコードを見てみると、現状でも改行、タブは大丈夫なのですね。
Add MariaDB to the Github actions by grooverdan · Pull Request #10062 · php/php-src
MariaDB (最新、安定版、ナイトリー) のテストを Github Actions に加えようよ!というイシュー。
これ意味あるの?とか、最新版だけで良くない?みたいな話がされています。
MariaDB が本番でそのまま使われるかは別として、世間の流れ的には抑えておくと良さそうなテストではありますね。
まだ、Draft なので、どうなるかは分かりません。
Assertion (zend_gc_refcount(&(ht)->gc) == 1) || ((ht)->u.flags & (1<<6))' failed. · Issue #10085 · php/php-src
PHP 8.3 の不具合報告。
不具合が混入したと推定されるコミットたち
配列周りの取り扱いで、入ったように思える。
コミッターの人が、「病的なコードなので、直るのかなんなのかよくわからん」と言っていて面白い。
もちろん、私にはわからんぞ。
Add CLEAN section to some IO tests by Girgias · Pull Request #10081 · php/php-src
--CLEAN--
というセクションを設けて、IO系のテストでの Fixture の処理が追加されたようです。
Anyone can lock a discussion for everyone else by getting "too heated" · Issue #10088 · php/php-src
too heated と言われてイシューがロックされてしまった!というイシュー。
ロックされたイシューがこちら
Internal 側でも、熱く盛り上がっていました。
議論の場は、Internal Mailing List であって、Github Issues じゃないよということで、ひとまず落着
Change status of BCMath into Maintained by frederikbosch · Pull Request #10089 · php/php-src
BCMath はちゃんとメンテナンスされてるよね。というわけで、 Unknown
から Maintained
に変更。
Internal stream casting should not emit lost bytes warning twice · Issue #10092 · php/php-src
<?php
$handle = fopen('http://example.com', 'r');
var_dump(stream_isatty($handle));
このコードを実行すると、同じWarning
が2回出てしまうというイシュー
修正内容を見ると、エラーをすでに送出したことをチェックしていなかったことが原因
Regex doesn't returns expected result · Issue #10096 · php/php-src
正規表現が意図する動作をしないというイシュー
複雑な正規表現で、Back Track が大量に発生していたのが原因だったので、クローズされました。
正規表現で無理やりなパースを行う事例は結構あると思うのですが、 pcre.backtrack_limit
という設定を超えては Back Track してくれませんのでご注意。
こういうケースでは、正規表現を特定の用途に絞るか、対象の文章を少なくするなどの工夫が必要かと思います。
コメントでは、U
フラグを指定して、「欲張り」しないようにしてあげたら?などのアドバイスもありました。
curl_setopt(_array) should warn on errors · Issue #10097 · php/php-src
もともとは、curl で特定のオプションの設定が反映されないというイシューでしたが、curl_setopt
及び curl_setopt_array
がエラー発生時に Error にしないというタイトルに変更になりました。
サイレントエラーは、実に見つけにくいですね。
realpath() with empty path should return false · Issue #10101 · php/php-src
file_exists
is_dir
の場合、空文字の入力が渡されると、false が返ってくるのに realpath
ではカレントディレクトリが返ってくる。これは一貫性がないのでは?というイシュー
Null Coercion といい、空文字が渡されたときの戻り値といい、このあたりの一貫性問題は基本的に後方互換性を破壊してしまうので難しいところではありますね。
Add Randomizer::nextFloat() and Randomizer::getFloat() by TimWolla · Pull Request #9679 · php/php-src
RFC が受理されたため、実装が master にマージされました。というわけで、お試ししたい人は新しいメソッドを利用することが可能です。
json_decode() fails on nested input of around 10000 characters. · Issue #10104 · php/php-src
深くネストした JSON で json_decode
が失敗するというイシュー
ネストした JSON の例
[[[[[[[[[[1]]]]]]]]]]
ext/json
の Makefile を見ると、下記のコードで parser が出力されています。
$(BISON) --defines -l ext/json/json_parser.y -o ext/json/json_parser.tab.c
json_parser.tab.c
では YYMAXDEPTH = 10000
となっているため、これが nest 10000 が上限となっている理由です。
そもそも、そんなにネストした JSON って... という気持ちになりますが、自前でコンパイルすれば、変更することはできそうですね。
php_admin_[flag|value] falsely applies config changes · Issue #10117 · php/php-src
php_admin_flag
の設定によって、誤って ini の設定が上書きされるという不具合。
Opcache による設定キャッシュが主原因と見られるので、下記イシューが要チェックです。
本番で、新しめの PHP を使っている場合は、注意する必要がありそうです。
PHP :: Bug #81743 :: XSS via PDOException error
HTML_ERRORS の設定にもよりますが、PDO の例外経由で XSS を発生させられるというイシュー。先週も取り扱ったような気がする...。
Discussion