🐥

今週の PHP 2022-12-31 〜 2023-01-06

2023/01/25に公開

PHP のメーリングリストから、気になった情報をピックアップします。

Internal

What to do with opaque GMP objects which allows instantiation - Externals

GMP のコンストラクターが、最低限必要なパラメーターをセットしないので、おかしなインスタンスが生成されてしまうというイシュー。

正しいコンストラクターに直しましょうというもっともな方向に落ち着きました。

https://github.com/php/php-src/pull/10225

update php.ini variables_order setting to EGPCS to reflect documentation - Externals

php.inivariables_orderという設定項目があります。
これは、スーパーグローバル変数へのデータ読み込み設定なのですが、ドキュメントでは EGPCS がデフォルトと書かれていますが、最近の PHP だと GPCS が設定されています。

ドキュメントには、ES とハレーションを起こすから、S でいいよという風に書かれています。S$_SERVER へのデータ読み込みですから、PHP をウェブアプリケーションとして利用する大半のユーザーにとっては、これが正しい設定と思います。

ドキュメントと乖離があるから、EGPCS にしようという意図のメールなのですが、何しろ反応がなさすぎて、話は止まっています。

個人的には、ドキュメント側を直したらと思います。

該当メールの内容の PR https://github.com/php/php-src/pull/10182/files

DateTimeImmutable::modify() return type: doc or language bug? - Externals

DateTimeImmutable::modify() の戻り値は、DateTimeImmutable となっているが、static じゃないのですか?というお便り。

https://3v4l.org/j9ZSo

実際に DateTimeImmutable を継承した SubClass が返却されているので、戻り値は static が正しそうです。

DateTimeImmutable は継承して使うものじゃないから、やめなよという論調の返信が来てますが、だったら継承できないようにしないと無理があります。それに Carbon のように、もはや手遅れなパターンもあります。

結局、どうしようか??という結論が出ぬまま空中に浮いています。

PHP support for matrix operations - BLAS, LAPACK. - Externals

機械学習をやられている方からのお便り

BLAS, LAPACK といった行列計算、統計的化学計算を行うライブラリーの拡張についてどう思いますか?という話です。

それ、Tensor で出来るよという返信がありました。

https://github.com/RubixML/Tensor

OpenBLAS や LAPACK もサポートしているので、確かに質問者さんの要望は満たせていそう。

残念ながら、PHP 8.2 でうまく動かなったという返信がきていますが、おいおい修正されることでしょう。

[RFC] Voting Result for More Appropriate Date/Time Exceptions - Externals

より適切な例外クラスをもたせようという Date/Time 系の RFC が受理されました。めでたい。

リリース

各種リリースがありました。ChangeLog を見れば一目瞭然で、8.0 系はアクティブサポートがありません。各位におかれましては、8.1 系以上へのアップグレードをおすすめいたします。

[RFC][Vote] Dynamic class constant fetch - Externals

やった〜〜〜。動的定数フェッチが受理されました。

こんなことが出来るようになります。

class Foo {
    const BAR = 'bar';
}
$bar = 'BAR';
 
// This is currently a syntax error
echo Foo::{$bar}; 

この挙動は Enum Case に対しても働きます。なので、今までやりたくても出来なかった Enum Case の動的指定が出来るようになります。胸アツ。

Microseconds to error log - Externals

久々に動きがありました。色々意見をもらった結果として、RFC としてまとめるほうがいいよね。でも時間かかりそうだけど、大丈夫かな、どうしようかな......

というような返信がありました。応援していきたい。

Bugs

mb_detect_encoding() results for UTF-7 differ between PHP 8.0 and 8.1 (if UTF-7 is present in the encodings list and the string contains '+' character) · Issue #10192 · php/php-src

mb_detect_encoding を使って、 + 含まれた文字列を判定すると、UTF-7 と誤診されてしまうというイシュー。

この挙動は、PHP 8.1 以降で発生しているので、おそらくは、 Major Overhaul of mbstring で発生した不具合。

誤診されるだけなら、問題ないかなと思ったのですが、 mb_convert_encoding と組み合わせると、なんと + が消えます。

https://3v4l.org/Ib2Fd

すでに UTF-8 の文字列である入力文字を UTF-7 と誤診したため、誤った文字コード変換が行われた結果 + が消えてしまいます。
ユーザー入力値の意図しない改ざんにつながるので、コレは深刻に見えます。

このイシューは、このあと iconv でも同様の事象が発生するという展開を見せます。

結果的には、8.0 以前の PHP でも UTF-7 から UTF-8 の変換を行うと + が消失するということがわかりました。

まとめると

mb_detect_encoding が 前後に空白を含む+を見つけると UTF-7 と誤診してしまうことが問題の核心でした。ワークアラウンドとしては、 mb_detect_encoding の候補文字コードリストから UTF-7 を取り除けばOKです。

PHP自体の対応としては、 mb_detect_encoding が 前後に空白を含む + を見つけても、 UTF-7 と判断しない方向で進みそうです。

multiple expressions operator (comma) · Issue #10196 · php/php-src

カンマを使って、複数の文を一つにまとめたいというイシュー

int $x=1, $y=2, $z=3;

C言語で見るような構文です。PHP でも for文の条件などでは一部使えるようにみえるので、文法として正式に全体で使えるようにしたいというもの。

https://3v4l.org/n3EPc#v8.2.1

新フィーチャーなので、RFC 作ってねの流れになりました。個人的には合ってもいいかな〜くらいの温度感なので、フィーチャー入りは難しそうな気もする。

Incorrect arithmetic calculations when using JIT · Issue #10195 · php/php-src

JIT の不具合により、数学的計算がおかしくなっていたというイシュー。すでに JIT の不具合が修正済みなので、現在は再現しないようですが、こういうケースもあるのだなということで、驚きました。

fgets() sometimes does not read a full line · Issue #10198 · php/php-src

fgets がたまにファイルをちゃんと読み込んでくれないというイシュー。AWS Fargate で、ファイルは EFS に乗っているということで、少し状況は特殊に見えます。かつ、cronjob で実行しているスクリプトだということです。
まだ、原因究明中です。

Update SJIS-mac mappings to use Unicode codepoints which were added after Unicode 1.0 by alexdowad · Pull Request #10264 · php/php-src

PHP勉強会 vol 148 で、てきめんさんが言及されていたイシューのうちの一つですね。SJIS-mac は昔の Mac のコードポイントで、古(いにしえ)の印刷所などで使われているようです。そのため、mapping を更新するのは、BC Break になるよということでした。

これは、そのままにするしかない気がします。

New function mb_str_pad (multibyte str_pad) · Issue #10203 · php/php-src

やった〜。 mb_str_pad だよ!RFCが出るのかな?私が使うかどうかは分かりませんが、マルチバイト圏では喜ばれそうです。

new function for basic filesystem quota evaluation · Issue #10210 · php/php-src

Disk の空きスペースとかを取得する関数がほしいというお便り。

disk_free_space , disk_total_space と命名されています。

RFC作ってねになりました。

cURL: Support of SSL_OP_IGNORE_UNEXPECTED_EOF context option · Issue #10215 · php/php-src

実は、自分のブログでも取り上げたのですが

hanhan's blog - PHP と OpenSSL 3 の話

OpenSSL 側は、対応済みのようですが、cURL 拡張は未対応のようで、同じエラーがまだまだ出てしまうようです。これについて、PHP 全体で挙動が一致するようにするためにも、cURL 拡張でも同オプションをサポートすべきというイシュー

そうだとは思うけど、upstream で対応してほしいよなぁという意見が出ています。つまり cURL 側がサポートしてくれないとという話です。

そして、話は停止しています。大事な話だけに、ちょっと気になる。

http_build_query() skips Stringable params · Issue #10229 · php/php-src

http_build_query は、連想配列から GET のパラメーター文字列を作ってくれる関数です。

このイシューは、Stringable つまり文字列になる可能性があるパラメーターの要素がスキップされているというものです。

https://3v4l.org/QgTBU#v8.2.1

修正の PR は下記で行われています。

Fix GH-10229 http_build_query() skips Stringable params by Girgias · Pull Request #10235 · php/php-src

しかし、後方互換性を考えると、ちょっと複雑です。下記は、複数のメンバ変数を持つ無名クラスが、__toString を実装している場合です。
現状では、メンバー変数の配列としてパラメーター化されるものが、string キャストされた場合と大幅に異なってしまいます。

https://3v4l.org/nH479

無名クラス、無名関数を使った要素は、条件付きの複雑なパラメーターを宣言的に使えるので、便利そうである反面、挙動を深く理解していないと不具合を生みそうですね。

Weird behaviour when a file is autoloaded in assignment of a constant · Issue #10232 · php/php-src

constant の読み込みに関連して、autoload が発生すると、ファイルの require に失敗するという話ですが、単純にファイルパスがおかしいだけですね。

コメントにもありますが、 include_path を指定するか、 dirname(__FILE__) を使って、絶対パスで require すれば動きます。この辺は PATH に対する理解が必要です。

var_export() added leading backslashes in PHP 8.2 · Issue #2145 · php/doc-en

PHP 8.2 になってからは、バックスラッシュが var_export の出力に足されていますが、ドキュメントに書いてなかった案件。関連イシューは下記です。

Removed warning about missing namespace leading backslash in `var_export()` docs by Ocramius · Pull Request #1472 · php/doc-en

ドキュメント側は、バックスラッシュについての挙動が変わったタイミングで、注意文が消されています。

ドキュメントに修正が入って、クローズされています。

https://github.com/php/doc-en/commit/0f27fadf81b66268edf545f13891401b4d53cc38

Discussion