🐡

今週の PHP 2022/10/22 〜 2022/10/28

2022/10/29に公開

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

Internal

SQLite3: implement session extension - Externals

https://externals.io/message/118872

SQLite3 の Session 拡張の実装についてです。

https://www.sqlite.org/sessionintro.html

The SQLite3 session extension allows to create changesets from a
database, that is to store a set of changes that have been done, and
either revert them, or apply them to another database.

つまり、これを PHP の SQLite3 拡張として実装すれば、インメモリーみたいに使って、高速な SQLite の扱いができるかもってことでしょうか?
ちょっとおもしろそうですね。

シェアードナッシングなモデルだと旨味が無いですが、Swoole などのモデルだと超高速動作が期待できるかもしれません。

Microseconds to error log - Externals

https://externals.io/message/118865

Github Issue から始まった議論が、Internals に降臨

ミリセカンドを出力する新規のエラーログ関数を作成という方向に動きつつあり。
RFC なのかな??

[RFC] [Discussion] SQLite3: remove warnings, move to exceptions - Externals

https://externals.io/message/118873

SQLite3 クラスにおいて Warning を出す代わりに例外を出すようにしましょうという RFC の相談です。

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

現状の SQLite3クラスのドキュメントは下記

https://www.php.net/manual/ja/book.sqlite3.php

今の所、どのような手順で warning を非推奨にして、例外をデフォルトの挙動にすべきか?ということについて、識者がコメントしてくれています。
RFC は、コメントを取り入れて成長中。

8.3 -> 非推奨、9.0 -> Warning撤去 みたいな流れの提案になりそう。

Proposal: Expanded iterable helper functions and aliasing iterator_to_array in iterable\ namespace - Externals

https://externals.io/message/118896

8.2 で採択された https://wiki.php.net/rfc/iterator_xyz_accept_array について、更に追加の提案です。

iterator_to_array という名前は、すごく紛らわしいので iterable という namespace をつけて alias しようというもの

つまり

iterator_to_array -> iterable\to_array
iterator_count -> ietrable\count

という具合です。

リリース

https://www.php.net/ChangeLog-8.php#8.0.25

PHP 8.2.0RC5 もリリースされました。リリースがどんどん近づいてきてます。もう一ヶ月を切りましたね。

Bugs

Crash when memory limit is exceeded during generator initialization · Issue #9801 · php/php-src

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

Generator の生成中に memory_limit を超えると Seg V が起きるというもの

例によって、修正は1行だったりする。

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

順次 backport されるようなので、 8.0, 8.1 を使ってる人は、そのうち対応が入ります。

Add ARRAY_UNIQUE_IDENTICAL option by iluuu1994 · Pull Request #9804 · php/php-src

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

比較できないオブジェクトなどでも array_unique ができるようにするオプションの PR です。
先週までは、ARRAY_UNIQUE_UNSORTED という名前で、他の PR が出てましたが、いろいろな話し合いの結果、ちょっとオプション名が変わりました。

ポイントは、このオプションを指定すると、比較できないオブジェクトでも、array_unique ができるようになる代わりに、計算量が増えるということです。
あくまで、数の少ない配列でやりましょうね。

ちなみに、まだ Draft です。

この PR の元になったイシューは、 https://github.com/php/php-src/issues/9775 です。

segmentation fault when sending SIGINT to PHP embedded in another program · Issue #9649 · php/php-src

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

シグナル関連の修正

スレッド周りでのシグナルの取り扱いに関する修正です。FrankenPHP 関連。

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

[RFC] Implement dynamic class const fetch by iluuu1994 · Pull Request #9793 · php/php-src

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

RFC に向けた PoC のイシューが立ってます。

下記のように、名前から定数値を取得したいという要望への対応です。

Foo::{$bar} ?? 'Bar';

もともとの動機は、Enum を Enum 名から fetch する fromName の要望が多かったから、ということです。
現状の Enum では、 from tryFrom というメソッドを使って、Backed Enum の値から、Enum を fetch することはできますが、Enum の Case 名から動的に取得することはできませんでした。

PDO::lastInsertId returns 18446744073709551615 instead of -1 · Issue #9811 · php/php-src

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

こんなテーブルを作って

CREATE TABLE `max_id` (
  `id` int NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2147483647 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

負の数で insert をすると

<?php
$pdo = new PDO("mysql:dbname=test;host=127.0.0.1", 'root', 'password');
$stmt = $pdo->prepare("INSERT INTO max_id (id, title) VALUES(?, ?)");
var_dump($stmt->execute([-1, "C"]));

"18446744073709551615" が返ってくるという不具合報告

PK は負の数になりうるが、 mysql_insert_id の戻り値が unsigned なので、変換されているのではという推測。

mysql 側のドキュメント案件なのでは??

Limit stack size by arnaud-lb · Pull Request #9104 · php/php-src

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

Stack size をチェックして、例外を投げようという PR

zend.max_allowed_stack_size という設定値が導入されています。
自分で設定することも可能ですが、デフォルトは実行されているプラットフォームに合わせて、自動でスタックサイズを計算してくれます。

これにより、今までは開発者が防げなかった StackOverFlow を例外として検知することができます。

修正箇所をみてみると、 stack_limit をコンテキストとして保持して、比較することでスタックオーバーフローを検知するようです。
もしかして、若干性能に影響したりするのでしょうかね?

Add new core autoloading mechanism for classes and functions by Girgias · Pull Request #8294 · php/php-src

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

新しい autoloading mechanism の PR です。
っていうか、最近、この手の Core に手を入れる系の修正提案が多くてびっくり。

RFC のための PoC っぽいので、Internal で議論を見学しつつ、コードの修正内容を追っていきたいところですね。

Location changed on error messages with PHP 8.2.0RCx · Issue #9771 · php/php-src

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

Error Message の指し示す行数が変わっているのだが?というイシュー

これは、意図された変更で、パラメーターが複数ある場合にエラーが示す行数がおかしいという指摘を受けて変更されたものです。

Wrong line number reported in case of a multiline parameter list · Issue #8810 · php/php-src

UPGRADING に追記しましょうねということで、おそらく解決。

Segfault zend_mm_alloc_small · Issue #9795 · php/php-src

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

Nginx + php-fpm 環境での Seg V の報告

JIT 関連で引き起こされているようで、下記の設定項目をいじくると Seg V の発生レートが変化するとのこと。

pcre.jit => 1 => 1
pcre.recursion_limit => 100000 => 100000

8.1.11 ということなので、もしかしたら、8.1.14 に上げると直ったりするのだろうか。

Allow extending readonly classes by non-readonly ones by kocsismate · Pull Request #9827 · php/php-src

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

Readonly class を Non Readonly class から継承可能にしようという PoC
RFC の議論は https://externals.io/message/118554 で行われています。

Readonly class に関しては、オブジェクト指向プログラミング関連の論文などをベースにしたものではなくて、
変更できないオブジェクトがほしいというユーザーからの要望で生み出されたものなので、裏付けが希薄で議論も難しそう。

8.3 に向けて、Readonly が決着をつけていけるのか、要注目

Mysqlnd: packet headers bigger than buffer (4096) miss DB errors and put driver in inconsistent state · Issue #9787 · php/php-src

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

Mysqlnd のイシューです。

packet のヘッダーサイズが Buffer サイズより大きいと、DB エラーが検知されず、コネクションも開いたままになるというバッファーオーバーフロー的な不具合

修正をみると、ハードコードされたバッファーサイズの修正や、ヘッダー読み込み部の微修正が入っています。

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

Fix pre-PHP 8.2 compatibility for php_mt_rand_range() with MT_RAND_PHP by TimWolla · Pull Request #9839 · php/php-src

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

よくわかってないですが、ext-rand の修正の残りものみたいなやつなのでしょうか???

Array unpack inside array literal is slower than array_merge() · Issue #9794 · php/php-src

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

配列のアンパッキングが、array_merge より遅いというイシュー

まあ、こんなやつですね。

$array_1 = ['foo', 'bar'];
$array_2 = ['baz', 'qux'];

$array_unpacked = [...$array_1, ...$array_2, ...['quux']];
$array_merged   = array_merge($array_1, $array_2, ['quux']);

8.1 からは、文字列キーのものにも対応しています。

Packed Array に対する処理が最適化されていないというコメントが入ってますが、Packed Array とは....

Discussion