今週の PHP 2022/07/30 〜 2022/08/05
PHP のメーリングリストから、気になった情報をピックアップします。
Internal
文字列が JSON かどうかを判定する is_json
関数の提案です。
- json_decode とエラー補足を行うことで現状でも達成できる
- json_decode はオブジェクト生成を行うし、memory_limit を突破してエラーになるリスクがある
- 文字列が json かどうかだけ知りたいときがある
というあたりが RFC の動機だったようです。JSON 形式チェックを短時間に大量に行うようなケースであれば、効率が良くなりそうです。
※ 実際に RFC を提出した方の会社では JSON 形式チェックを大量に行う必要があって、memory 使用量やパフォーマンスで懸念がでていたそうです。
NO も YES も意見が出てきています。
結局形式チェック時に文字列をメモリにロードしなきゃいけないから、同じでは?
PoC を見せてほしいという意見
投稿主は、 memory_get_usage
で前後のメモリ使用量を出しているが、 memory_get_peak_usage
で実際にメモリ使用量が下がっていることを確認してほしいとう意見
関数名は is_json_valid
がいいのでは?という意見
json_decode
に Validation のみを行うフラグをオプションで追加したら?という意見
この関数は、本当に使いみちがあるのか? json_decode
しないで、json
形式であることだけを確認したいなんてことあるのか?
もし、memory_limit より大きい文字列が json かどうかを判定できるなら、YES に入れるよ。といった意見
APIサーバーで、payload が json かどうかを事前チェックする用途なら理解できる。という意見
ユーザーランドでの実装は、Laravel, Symfony などでたくさん行われており、より軽快に動作する組み込み関数は、実際に必要とされていそう。
filter_var($possibleJSON, FILTER_VALIDATE_JSON)
こういうのはどうだろうか?という提案も
いずれにしろ、議論は活発に行われて、目的も明確になってきたので、RFC が提出されそうです。
PoC はまだ出てないのですが、イシュー主のベンチマークでは、 is_json
のメモリ使用量は json_decode
と比べても最小で済むようです。ベンチマーク上は、ほとんどメモリ使用量が増えていませんでした。
array_merge() vs array unpacking performance
3v4l はちょっとした計測エビデンスにも使えますね。
[...$arg1, ...$arg2]
PHP 8.0.22 Released
8.0.22 https://www.php.net/ChangeLog-8.php#8.0.22
8.1.9 https://www.php.net/ChangeLog-8.php#8.1.9
8.2.0 Beta 2
xoshiro** edge case
All zero state
-> bug fix 側で修正が出てる
乱数の世界は、とにかく知らない単語が多い。
XOR して Shift して Rotate するので、 Xoroshiro
らしい。
Bugs
The last item of list variable will be error when use reference of variable. · Issue #9204 · php/php-src
foreach で Reference を使った際の挙動に対するイシュー
なぜ、1 2 3 4
にならないのか?これについては、公式マニュアルにも記載があります。
意図通りに動いてもらうには
-
unset を使う
https://3v4l.org/nMXP7 -
変数名変える
https://3v4l.org/8v1fI
細かく解説すると
$it
には $list[3]
の Reference がセットされています。つまり、2回目の foreach は継続的に $list[3]
の内容を表示しています。
ループが回るに従って、$list[3]
の内容が上書きされるため、最終的に key = 3 の内容が表示されるときには、一個前の 3
がセットされているので、1 2 3 3
と表示されます。
0 => [1, 2, 3, 1]
1 => [1, 2, 3, 2]
2 => [1, 2, 3, 3]
3 => [1, 2, 3, 3]
foreach
で参照を使う場合は、空間計算量(メモリ)節約が一番の理由になりそうですが、上記のような挙動を考慮して書かないと、不具合を生む原因になりますね。
Obnoxious error in build/gen_stub.php "PHPDoc param type is unnecessary" · Issue #9183 · php/php-src
php-src の build/gen_stub.php
における PHPDoc param type が面倒くさいので消したいというイシュー
そもそも gen_stub.php
の役割が分かっていないのですが、議論の結果として、Annotation の @param
チェックが削られてマージされています。
test とか実行するときの stub なんでしょうね。多分、phpt とかの実行してみると、役割が明確にわかりそうな気がする。
というわけでやってみよう。
make test TESTS=ext/xml/tests/xml001.phpt
こんな感じで、テストを実行してみると、build/gen_stub.php
がコールされていることが分かりました。というわけで、テストで必要な共通な関数群、定数郡を定義するためのファイルでした。
今回の話については、 setType
関数が引数の型チェックをしている箇所で、@param
までチェック対象だと、メンテがつらいということらしい。
この辺は、コミッターの人たちじゃないと、気持ちは分かりづらそう。
Randomizer::pickArrayKeys() has intransparent external behavior · Issue #1731 · php/doc-en
master に対するイシューとして上がってきている。
しかし、array_rand
を使ってみると、7.1 以降は同じ挙動になっていることがわかる。
というわけで、ドキュメント修正ということに。
setcookie has an obsolete expires date format · Issue #9200 · php/php-src
setcookie の日付形式がおかしいのでは?というイシュー
<?php
setcookie('expires-format-test', 'test', strtotime('now + 1 minute'));
Set-Cookie | expires-format-test=test; expires=Sat, 30-Jul-2022 05:12:54 GMT; Max-Age=60
RFC2616 のフォーマットの場合、以下の3つ
Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
これに乗っ取るとすれば、 日付形式のハイフンは違反では?と
これに対する返信は
このあたりでは、ハイフン付きの日付も許容されると書いてあり、違反ではないと。
ハイフンがない日付のほうが、仕様としては新しいが、これは緊急で直す案件ではないと。
この辺、RFC の相関関係とか歴史を知っておかないと、迷子になりそうな議論でした。
Function for getting first or last value from array · Issue #9199 · php/php-src
array_key_first
array_key_last
を使いましょうね。
この関数、どのタイミングで入ったんだろうと思って RFC を確認したら
PHP 7.3 からでした。
Language change じゃないから、50% + の Vote でOKという記述があって、Vote率は内容によって違うのか〜〜〜っという発見でした。
dl() breaks expectations regarding permanent or interned strings · Issue #9196 · php/php-src
関連イシュー
dl()
関数が、内部文字列周りで不具合を起こすというイシュー。
precision 0 -INF · Issue #9209 · php/php-src
何を言ってるのかよくわからないと思ったが、要するに precision 0
を設定した状態で、INF に引き算した結果が、PHP 8.1 系から変わっているんだが??というやつ
damianwadley さんがまとめてくれていた。
Starting with PHP 8.1.0, when precision=0, -INF serializes to "-". Negative numbers are unchanged.
そもそも、ini の precision
とは?
浮動小数点数に関して表示される最大桁数を指定します。 -1 は、数値を丸める際に拡張アルゴリズムを用いることを意味します。
ぴんとこねぇ。
Enum case as Array key? · Issue #9208 · php/php-src
Enum を Array の key にしたいよ!という話
すでに RFC もでていた
それがなぜ問題なのかを指摘しているコメント
StreamWrapper support for glob() · Issue #9224 · php/php-src
glob は使ったことがありませんでした。
macOS だと csh では使えました。
glob.h を include すれば C言語でも使えますね。パターンマッチするパス名を探してくれるコマンドです。
パス名?だから StreamWrapper に対応するべきものなのかどうか、私には判断がつきません。
そもそも StreamWrapper とは?
Brace expansions for fnmatch() · Issue #9223 · php/php-src
またしても、使ったことがない関数
fnmatch
なるほど、パターンマッチングができるんですね。
fnmatch も libc に含まれる関数のようで、PHP は C言語の薄いラッパーという概念を地で行く感じです。
このイシューですが、glob と fnmatch に brace expressions を追加するかどうか?という話です。
発端は、最近 python に入った以下の機能追加のようです。
diff を見ると イメージが凄くわきますね。
{pat1,pat2,...}
このパターンで、pat1, pat2 を or でマッチさせることができるというものです。
csh で試してみると glob コマンドで
glob {composer.json,composer.lock}
composer.json と composer.lock の療法を引っ掛けることが出来ました。なので、PHP 側が対応していないということのようですね。
試してみましたが、今は使えないようです。このへんは使えるようになってもいいなと思いました。
Segfault in zend_accel_class_hash_copy · Issue #9164 · php/php-src
何を直しているんだか、全然わからねぇな!
私にわかるのはバグレポートが実に正確だということです。こういうバグレポートを私も書きたい。
trim support for multibyte spaces / mb_trim() · Issue #9216 · php/php-src
mb_trim !!!!
mbstring の拡張に入るらしい。しかし、全世界にはたくさんの空白があるんだねぇ。
Filenames with leading dots or spaces are not properly handled · Issue #9227 · php/php-src
Windows環境において、ファイル名の末尾にドットが入っていると、適切にファイルハンドリングされないという不具合。
こういう不具合がまだ残っているのですね。
Partially support first-class callable syntax in constant expressions · Issue #9236 · php/php-src
constant に 第一級 callable を設定できるようにしようというイシュー。
RFC プロセスのご案内
第一級 callable というのは、8.1 で追加された。callable から無名関数を生成する記法
【Big BUG】Why 439!=4.39 * 100, But 438==4.38 * 100? · Issue #9243 · php/php-src
出ました。IEEE-754
定期的にイシューが寄せられる、浮動小数点関連です。小数点は近似計算になるということを覚えておきましょう。
Segfault with array_multisort + array_shift (packed arrays?) · Issue #9244 · php/php-src
<?php
$items = ['foo' => 1, 'bar' => 2];
$order = [4, 3];
array_multisort($order, $items);
var_dump(array_shift($items));
array_multisort と array_shift の組み合わせで、seg fault が起きるというイシュー。
8.2-dev なので、現状リリースされているバージョンには影響はなさそうです。
Fix の内容をみると sort したあとに zend_hash_rehash を行っていないことにより array_shift がセグフォを出すようです。
zend_hash_rehash のコードは今度追ってみようかな。
Assertion when fetching property of "bad" magic constant · Issue #9136 · php/php-src
マジックメソッドのプロパティを参照しようとしたときの、エラーメッセージがおかしいというもの
zend_compile.c:9852: zend_compile_const_expr_magic_const: Assertion `ast->attr == T_CLASS_C' failed.
Fixはこの2つ
ext-Random周り
PcgOneseq128XslRr64::jump should not allow negative $advance · Issue #9212 · php/php-src
ext-Random の polyfill を書いている人からのイシュー。
PcgOneseq128XslRr64::jump()
が負の整数を受け取ると、unsigned int にキャストされて整合性が取れなくなるので、負の整数を受け取らないようにしませんか?という提案
こちらはパッチ。例外スローが追加されている。
Random: Xoshiro256StarStar does not reject the invalid all-zero state · Issue #9249 · php/php-src
ext-Random のbug fix
不正な入力値や、暗合生成機が 0 を生成した場合に Retry するなどのコードが追加
More ext-random integer overflow · Issue #9190 · php/php-src
整数オーバーフローの修正。
いやー、どういうことだが、よくわからんですね。
MT_RAND_PHP causes undefined behavior · Issue #9191 · php/php-src
-> #9190 と同じFix
おまけ
Discussion