🌵

今週の PHP 2022/07/23 〜 2022/07/29

2022/07/30に公開

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

PHP 8.2 の Feature Freeze を過ぎたので、今週は Internals が少なめでした。

Internal

Character range syntax ".." for character masks

先週に引き続いて、.. の議論が続く。

https://3v4l.org/2Y0q4

サンプルは、strcspn で、もし .. が使えたら a..zA..Z って書けて楽ちんだねと。

PHP 8.3 に向けて RFC が出てきそうな予感です。

[RFC Review] is_json(string $string): bool

引数の文字列が json であるかどうかを検査する関数の提案です。まだ RFC にはなっていなくて、RFC の準備段階でのフィードバックを求めている感じです。

既存のやり方だと、 json_decode の結果を検査して、エラーが出ていないか?ちゃんと配列でデータが返ってきているかなどで判定するコードが書かれていそうです。

ただ、利用用途を考えると、多分 json だったら、その中身使うんですよね?だったら、 json_decode で良くないか?という気もします。

CSPRNG の実装について

先週に引き続いて CSPRNG

cryptographically secure pseudo random number generator 暗号論的疑似乱数生成器

についての議論が続いている。

現状の実装が libc に依存していることに対する懸念(Alpine は musl)

割と否定的な意見が出ていたなかで、今週は Zeriyoshi さんから PoC(Proof of Concept) が提供された。
※要するにサンプル実装

議論の中で使われていたベンチマークの抜粋

現在の実装 libc の system call が大きい

Overhead  Command  Shared Object          Symbol
  32.50%  php      [kernel.kallsyms]      [k] preempt_count_sub
  30.00%  php      libc.so.6              [.] syscall
  18.33%  php      [kernel.kallsyms]      [k] do_el0_svc
   2.50%  php      php                    [.] execute_ex
   1.67%  php      [kernel.kallsyms]      [k] __this_cpu_preempt_check

real 0m0.069s
user 0m0.025s
sys 0m0.044s

PoC の結果。php で実行が済んでいる。パフォーマンスは 4倍ちかい。

Overhead  Command  Shared Object      Symbol
  31.58%  php      [kernel.kallsyms]  [k] __flush_cache_user_range
  15.79%  php      php                [.] _efree
  10.53%  php      php                [.] zend_register_functions
   5.26%  php      [kernel.kallsyms]  [k] __rcu_read_unlock
   5.26%  php      [kernel.kallsyms]  [k] page_add_file_rmap
   
real 0m0.016s
user 0m0.009s
sys 0m0.007s   

これに対して、すでに OpenSSL が良い CSPRNG が提供されているぞ!という反論もあったが、それに対しては、もっと古い OpenSSL 使っている現場もあるし、そもそも ext OpenSSL を使ってない人もいるよね?という反論もあり
やはり互換性の落とし所を見つけるのがいつも大変。

とりあえず、現状の getrandom の実装(libc依存)維持しつつ、将来的には VDSO を使った実装に libc 側が切り替わるので、それを待つという方針になったように見えるが、ついていけないじゃん?

Man page of VDSO

というわけで、現状とにかく System Call のオーバーヘッドが大きいわけだが、getrandom の利用用途を考えると、それは IO などに比べれば無視できるレベルなので、PHPレベルではなく、カーネルレベルでの改善を待つのでも良いでしょうということらしい。


Bugs

Datetime 系

https://bugs.php.net/bug.php?id=75035&edit=1

foreach ([PHP_INT_MIN, PHP_INT_MAX] as $extreme) {
    $i = 64;
    while ($i --> 0) {
        $d = new DateTime('@' . ($extreme >> $i));

こういうのって、そもそも対応するべきなんですかね???という気もしてしまう。

PHP :: Bug #79717 :: Inconsistent handling of 5-digit years

https://bugs.php.net/bug.php?id=79717&edit=1

9999年の1年後に不具合が露見するタイプ 10000 ではなく 0000 になってしまう。
2000年問題の時に見たようなやつ

PHP :: Bug #79041 :: PHP 7.4 changed foreach behavior for DateTime object

https://bugs.php.net/bug.php?id=79041&edit=1

これは won't fix そもそも property 自体が安定した系ではない。

PHP :: Bug #78966 :: strtotime transform error with

https://bugs.php.net/bug.php?id=78966&edit=1

これは ナノ秒 精度の strtotime が失敗する件。 -> fix 済み

https://zenn.dev/khasunuma/articles/introduction-to-iso8601

iso8601 の仕様としてナノ秒は入っているのだろうか?

DateInterval 1.5s added to DateTimeInterface is rounded down since PHP 8.1.0 · Issue #9106 · php/php-src

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

0.5 秒刻みのインタバールが丸められてしまうという不具合。修正済み。(PHP8.1系のみ)

DateTime object comparison after applying delta less than 1 second · Issue #8964 · php/php-src

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

これも 8.1系の同系不具合

extreme な strtotime 系。

これはそもそも不具合ではない。

PHP :: Bug #77941 :: strtotime "next <weekday>"are off by one for dates parsed from calendar week
https://bugs.php.net/bug.php?id=77941&edit=1
PHP :: Bug #78080 :: strtotime('last <day of week> + 7 days') incorrect result https://bugs.php.net/bug.php?id=78080&edit=1
PHP :: Bug #79403 :: DateTime::construct inconsistent results with "first day of" https://bugs.php.net/bug.php?id=79403&edit=1

"VirtualProtect() failed" entries in apache error.log

https://bugs.php.net/bug.php?id=79751&edit=1

PHP 8 以上で Windows で Apache ModPHP 動かしている場合に JIT のエラーが出ているらしい。
特に対応はされておらず、エラーの報告が定期的にきている状態。

関連していそうなのがこれ
opcache.jit=1211 in php.ini causes apache to crash · Issue #9105 · php/php-src

Fix memory leak on Randomizer::__construct() call twice by zeriyoshi · Pull Request #9091 · php/php-src

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

Randomizer の コンストラクターを2回呼ぶとメモリーリークする件。8.2 で追加される新フィーチャーの不具合報告。

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

2回呼ぶと例外を吐くということで修正完了

native php is_true and is_false? · Issue #9119 · php/php-src

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

is_null あるし、 is_trueis_false あってもよくね?というイシュー

まあ、なくてもよくね?ってなってクローズ。true/false 型が導入されるので、この話は再燃しそうな気がする。

api to set memory_limit to "at least" this much · Issue #7944 · php/php-src

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

少なくともこれくらいっという memory_limit をセットする APIがほしいというイシュー。
要するにすでに 4G って設定されていたら、1G で設定しようとしても 4G のままでいてほしいということ。
気持ちはわかるような気がする。

結局、実証コードをもとに議論を続けていった結果、
そんなことより、memory_get_limit のようなAPIで、実際に割り当てられている memory_limit を数値で取りたくない?という話になって

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

イシュー立てた人が気力を持ち続ければ、RFCが出てきそう。

array type improvements · Issue #9122 · php/php-src

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

list 型を作ろうぜというイシュー。
そのまま RFC のご案内になりました。

PHP crash · Issue #9127 · php/php-src

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

str_shuffle が Windows でクラッシュするというイシュー。

8.2 の Random 実装の追加により発生。

Relocate JIT buffer close to PHP and achieve 2% more performance · Issue #8619 · php/php-src

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

JIT の buffer を PHP の近くに置くとパフォーマンスが2%上がるというイシュー。
よくわからんが、イシューを上げた人の PoC に近いものが 8.2 で取り込まれたらしい。

More ext-random integer overflow · Issue #9190 · php/php-src

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

ext-random の integer オーバーフロー

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

こちらと同じ原因によるもの。 CPUアーキテクチャーに依存した形で、期待した結果になっていないらしい。

Discussion