🌰

今週の PHP 2022/10/15 〜 2022/10/21

2022/10/23に公開

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

Internal

[RFC] Destructuring Coalesce

https://externals.io/message/118829

https://wiki.php.net/rfc/destructuring_coalesce

destructuring assignments (分割代入)
-> list などで、配列を一挙に変数にアサインするときに、初期値を指定できるようにしようという提案です。

<?php
[$a ?? "default value"] = $array;
list($a ?? "default value") = $array;

PHP のイシューにおいても、何度か要望が上がっていた機能です。
仕事でこういうコードを書くか...は、わからないですが、プライベートとか、自作ライブラリーとかだと実にほしいなと思います。

Casting array to any class

いわゆる DTO (Data Transfer Object) と呼ばれるものが、よく使われます。
この提案は、配列をクラス名でキャストすることで、DTO をかんたんに作れるようにしようというものです。

実装としては、 _set_state() を利用する形をとったらどうだろう?といっています。

コード例で書くと、こんな感じに連想配列をクラスのオブジェクトに変換できるようにしたい。と

class Fuga {
    public function __construct(
        public readonly int $x,
        public readonly int $y,
    ){}
    
    public static function _set_state(array $array)
    {
        $fuga = new Fuga();
        $fuga->x = $array['x'];
        $fuga->y = $array['y'];
    }
}

$arr = ['x' => 4, 'y' => 5];

$fuga = (Fuga)$arr;

_set_statevar_export を使った際に、オブジェクトを復元するために使われるマジックメソッドです。
それを、キャストにも流用してしまおうということです。

これに対して、名前付き引数とスプレッド構文を使えば、近しいことを今でもできるという返信

class Fuga {
    public function __construct(
        public readonly int $x,
        public readonly int $y,
    ){}
}

$arr = ['x' => 4, 'y' => 3];

$fuga = new Fuga(...$arr);

Should the engine be able to pass variables by reference of userland functions - Externals

https://externals.io/message/118847

[VOTE] Improve unserialize() error handling - Externals

https://externals.io/message/118813

unserialize の例外発生時の挙動改善の RFC ですが、一番メインになっている 例外の共通化については、雲行きが怪しそう。

Adding the OpenSSF Scorecards GitHub Action - Externals

https://externals.io/message/118864

https://openssf.org/

OpenSSF は、セキュリティ系のチェックツールらしいのですが、それのスコアを GitHub Action で集計しようみたいな相談。

すでに、実行自体はされているようで、現状のスコアは見れます。

https://api.securityscorecards.dev/projects/github.com/php/php-src

現在のスコアは 5.3 とのこと。

Microseconds to error log - Externals

https://externals.io/message/118865

とても、負荷の高いアプリケーションにおいて、エラーログにマイクロセコンドを出したいという相談。

現状のソースコード内では、秒に狭められてしまっているという

https://github.com/php/php-src/blob/master/main/main.c#L799

まあ、Monolog みたいなユーザーランドの解決策をつかってしまうな...自分は。

NULL Coercion Consistency - Externals

https://externals.io/message/117501

https://wiki.php.net/rfc/null_coercion_consistency

関数引数に、値の定まっていない変数を入れた際に、エラーになる挙動、ならない挙動が一貫していないため、一貫させようという一大事業です。

たとえば、htmlspecialchars は 8.1 以降で非推奨ですが、sprintf では null を渡しても問題なかったりします。

https://3v4l.org/ttDr2

Compact can't resolve outer scoped variables using short closures - Externals

https://externals.io/message/118850

$x = 123;
(fn() => compact('x'))();

compact が short closure 使ったときに、外のスコープを見れないという問題。
既知の問題ではあるようです。

compact 自体が非推奨になればいいのにという

Proposal to incrementally improve timeout and signal handling - Externals

https://externals.io/message/118859

PHP の Timeout や Signal ハンドリング関連の改善提案です。

この RFC を準備している dunglas さんは、FrankenPHP の作者です。
Go で PHP を embed していく過程で、様々なハマりどころがあったということで、ついに RFC を出して PHP 自体の改善提案!!

大まかにまとめると

  1. timeout の実装は ZTS に対応できていない
  2. Zend Signals はマルチスレッド環境で Seg V とかいろんな問題がでる

この2つを改善する提案です。

FrankenPHP はシェアードナッシングモデルの PHP を維持しつつ高速化を体現するために SAPI として実装された気鋭の勢力です。
これから要注目の SAPI にまつわる提案ですので、こちらも要チェック。

Bugs

opcache: add FrankenPHP to the allow list by dunglas · Pull Request #9755 · php/php-src

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

FrankenPHP っていう SAPI があるらしい。

https://frankenphp.dev/

Add destructuring coalesce by bwoebi · Pull Request #9747 · php/php-src

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

https://wiki.php.net/rfc/destructuring_coalesce

ディストラクティング合体演算子??

新しいRFC用 の PoC です。

キーが存在しないときのデフォルト値を設定するという仕様追加です。いまいち、用途がわからない...

Segmentation fault on PDO::sqliteCreateFunction with SQLite driver on PHP 8.2.0RC4 · Issue #9749 · php/php-src

https://github.com/php/php-src/issues/9749

SQLite driver のセグフォールト案件です。 PHP 8.2.0 RC4 でも出てましたが、修正されたようです。
ついでに xhprof への不具合報告もされていたようで、素晴らしいです。

Generator crashes when interrupted during a function call with extra named params · Issue #9752 · php/php-src

https://github.com/php/php-src/issues/9752

Generator に余分な名前付き引数を渡して停止させると、クラッシュするというイシュー
8.0系向けにもPRが飛んでいるようです。

潜在バグだったのですね。
修正内容は、たったの一行という。

https://github.com/php/php-src/pull/9753/files

Mysqli converts TINYINT to a string after SUM() if the result of SUM is outside TINYINT, even if MYSQLI_OPT_INT_AND_FLOAT_NATIVE is set to true. · Issue #9665 · php/php-src

https://github.com/php/php-src/issues/9665

以前にも紹介したこちらの不具合報告。 SUM をすると型が変わってしまうというものでしたが、

sum and avg is MYSQL_TYPE_NEWDECIMAL.

ということで、MySQL側の挙動に合わせるのであれば、文字列型で受けないと精度が変わってしまいますねということでした。
この挙動は、想定どおりなので、修正は無しでクローズになりました。

copy() target is blank in PHP 8.2.0-rc3 · Issue #9653 · php/php-src

https://github.com/php/php-src/issues/9653

VirtualBox の shared folder において、 copy でファイルが見つからない問題。
似たような事象に NFS マウントで遭遇したことがあるので、要チェックしてました。

修正を見てみると

https://github.com/php/php-src/pull/9656/files

copy_file_range というシステムコールをサポートしているかどうか?のようでした。

kernel 5.3 以降におけるファイルシステムまたぎのファイルコピーに対応させたということのようです。
これ、結構問題になりそうな気がしました。

一見して、理由がわからないやつ。

Duplicates returned by array_unique when using enums · Issue #9775 · php/php-src

https://github.com/php/php-src/issues/9775

ENUM を格納した配列にたいして array_unique しても unique にならないという報告
不具合として確認されました。

原因は、ENUMが比較できないからだというコメント

var_dump(Test::COURSES_ADMIN <=> Test::COURSES_ADMIN); // 0
var_dump(Test::COURSES_ADMIN <=> Test::COURSES_REPORTING_ACCESS); // 1
var_dump(Test::COURSES_REPORTING_ACCESS <=> Test::COURSES_ADMIN); // 1

まあ、Backed Enum の値を取得して、ユニークかけて、from で戻せば、できなくはないというコメントも。
https://3v4l.org/4uv5s

比較できない中身についても整列可能な ARRAY_UNIQUE_UNSORTED というオプションを追加する PoC が出ています。
ただし、 O(n^2) に計算量が上がってしまうとのこと。

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

Misleading error message for array unpacking of objects/enums in constant expression · Issue #9769 · php/php-src

https://github.com/php/php-src/issues/9769

配列 の splat operator を使ったときのエラーメッセージがおかしいというイシュー

修正は、もう来ています。

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

Refactoring 関連

Girgias さんが、所々のリファクタリングをやっています。

一見すると、修正行が多いので怯んでしまうのですが、コミットごとにみると、なんとか理解できます。

Discussion