🎉

今週の PHP 2023-03-18 〜 2023-03-24

2023/05/08に公開

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

Internal

First-class callable partial application - Externals

PHP: 第一級callableを生成する記法 - Manual

callable を生成する記法が、部分適用を受け入れないという件に関するお便り

以下は、メールにも掲載されていたコード例です。


// partial application
foo(bar(1, ...));

function foo(Closure $closure)
{
    $closure(2);
}

function bar(int $a, int $b)
{
    var_dump($a, $b); // 1, 2
}

bar メソッドの呼び出しに部分適用を使うことで、foo を実行したときに、一部の引数が適用済みという状態になっています。

PHP マニュアルにも、部分適用のはなしは載っていないですし、私自身も PHP では部分適用はできないという認識だったので、まあこれはできないようねという感じです。

部分適用については、過去に RFC が作られていますが、実装困難&名前付き引数の問題など、実装面での困難さや仕様詰めが難しかったらしく否決されています。

PHP: rfc:partial_function_application

可決されていたら、? を使うことで部分適用を利用することができていたようで、惜しいです。

PHP: rfc:arbitrary_static_variable_initializers

全会一致で可決されました。

static で宣言する変数について、任意の初期化方法が可能になります。

function bar() {
    echo "bar() called\n";
    return 1;
}
 
function foo() {
    static $i = bar();
    echo $i++, "\n";
}

これまでの仕様では、動的な式を使って初期化することはできませんでした。

PHP: 変数のスコープ - Manual

Can we get compile time routines? - Externals

相談内容としては、大きめの json ファイルの decode 処理があるので、compile 時に実行してしまいたい。というものです。Github Issue にも同様の相談が来ていました。

Can we get compile time routines? · Issue #10864 · php/php-src

Github のコメントにも書かれていましたが、下記のように json_decode した結果の配列を PHP ファイルとして吐き出した上で、require してしまうのが、現在できることかなと思います。

$data = json_decode(file_get_contents("large.json"), true);
file_put_contents("large.php", "<?php return " . var_export($data, true) . ";\n");

これは、実際に ISUCON などで、私もユーザー情報を配列化して、OPCache に載せるためにやった手段です。

やれる方法はあるのですが、若干面倒くさいのは事実なので、関数化されて予め実行するだけ良いとかになってくれると、ありがたいかもしれません。とはいえ、それも preload で出来ますね...

Bugs

Memory allocated by stream_context_create not released when destroying stream_socket_server · Issue #10885 · php/php-src

stream_socket_server が破棄した際に、 stream_context_create が確保したメモリーが解放されないという不具合。

修正内容を見ると、参照カウントが正しく行われていなかったのが問題のようです。

https://github.com/php/php-src/commit/122f1287a07c43d79c2c934d79d67e3fe194470b

FPM: error_log entries all on same line · Issue #10890 · php/php-src

error_log 関数が、全て同一行にエントリーを返すという報告。この事象に自分は遭遇したことがないのですが、まだま調査中らしいので、詳細は分かってないようです。

ちょっとだけ気になります。

FILTER_VALIDATE_URL returns false when it should return true · Issue #10901 · php/php-src

https://3v4l.org/atZSB

URL文字列に含まれる -x- は、urlencode した上でクエリストリングに付与しないと、URL文字列としては不正とみなされるという話。

https://stackoverflow.com/questions/2742852/unicode-characters-in-urls

モダンブラウザは、アドレスバーにあるURL文字列を %エンコードされた文字列として取得します。そのため、単体の -x- がURL文字列に含まれると不正と判断されるようです。

日本語の検索クエリが人間に読める状態になっているのはこのためですね。とはいえ、自分も仕事で遭遇したらちょっとハマってしまいそうです。

Wrong array sorting with NAN · Issue #10900 · php/php-src

NAN が入っていると、sort の結果が想定外になっているという件。

https://3v4l.org/fpR4G

NANってなんだろう?と思ったら、過去に自分がブログを書いていたので吹きました。

hanhan's blog - PHP における NaN とは

NAN は non-comparable だから、そもそも sort で安定した挙動はしめせないよ?というコメントが入っていました。NAN は sort しないようにしましょうね。

json_encode/decode simd by default? · Issue #10894 · php/php-src

simdjson という拡張があることを知らなかったので、そこからです。

PHP: Simdjson - Manual

この拡張は、json_encode/json_decode よりええやんけ、simdjson をデフォルトの関数挙動にしようよ!というお便り。

すでに2年前にインターナルで議論されていたようです。

[RFC] Bundling ext/simdjson into core - Externals

2年前の時点では、simdjson はできたばかりで、Linux ディストリビューションによってはコンパイルが出来ないという問題があったようです。

いずれにしろ、広範囲なユーザーに対して一定した使い心地を提供することが出来ないということで取りやめになっていました。

互換性の問題あるようで、もし使いたいなら pecl で使ったら?ということで、この件は close

OPCache with Enum and Callback functions results in segmentation fault · Issue #10914 · php/php-src

比較的新しめの PHP において、Enum やコールバックを使うコードで SegV がでているようです。もう少し情報が集まらないと判断が難しいところです。

JIT は一難去ってまた一難という感じで、まじで難しそう。

Possible Memory Leak with SSL-enabled MySQL connections · Issue #8979 · php/php-src

SSL で接続した MySQL 接続におけるメモリーリークの件、修正がマージされました。

Merge branch 'PHP-8.1' into PHP-8.2 · php/php-src@337973f

結局、 GC_REFCOUNT の取り扱いによるものだったようです。

Discussion