Slide 1

Slide 1 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 2020.12.12 PHP Conference Japan 2020 @hgsgtk Kazuki Higashiguchi PHP8の新機能を PHP内部コードのテスト phptから読む 1

Slide 2

Slide 2 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 当発表で得られるもの 1 2 3 PHP8の新機能を理解できる PHP内部コードのテスト phpt の読 み方がわかる PHPの機能をドキュメントだけでなく、 テストコードから調べられるようになる 2

Slide 3

Slide 3 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 3 phptからPHP8の新機能を読む ※ PHP内部構造の図は『Quick tour of PHP from inside』を参考 https://www.slideshare.net/jpauli/quick-t our-of-php-from-inside

Slide 4

Slide 4 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon @hgsgtk Kazuki Higashiguchi 東京に住まう Software Developer BASE BANK, Inc. Full Cycle Developer / Tech Lead 自己紹介 4 Dockerアプリケーション開 発実践ガイド > コンテナアプリケーションの設計 セオリー https://gihyo.jp/magazine/SD/archive/2020/202012 PHPにおけるユニットテス トとCI/CD > ユニットテストの育て方 https://gihyo.jp/book/2019/978-4-297-11055-0

Slide 5

Slide 5 text

#phpcon © 2012-2020 BASE, Inc. 5 “PHP Interpreter”の テスティングフレームワーク

Slide 6

Slide 6 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon “PHP Interpreter”のテスティングフレームワーク PHP自体のコード”The PHP Interpreter”(https://github.com/php/php-src) php-srcには、テストスイートとその結果を記録・レポートするテスティングフレームワー クが用意されている(https://qa.php.net/running-tests.php) PHPをビルドする過程で生成したMakefileを用いてmake testで実行する テスティングフレームワークとしての機能(run-tests.php) - テストスイート(*.phpt)の収集 - SUT (System Under Test) の実行 - 期待値を検証する - テスト結果のレポーティング 6

Slide 7

Slide 7 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 実行時の構造 7 $ make test TEST_PHP_EXECUTABLE=sapi/cli/php sapi/cli/php run-tests.php See also 『ソースコード(php-src)からPHPをビルドする流れと仕組みを手を動かしながら理解する』

Slide 8

Slide 8 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon make test実行結果 8 $ make test ...(省略) =========== TIME START 2020-12-11 08:32:20 =========== PASS EXPECT [tests/run-test/test001.phpt] PASS EXPECTF [tests/run-test/test002.phpt] PASS EXPECTREGEX [tests/run-test/test003.phpt] PASS INI section allows '=' [tests/run-test/test004.phpt] … (省略) ... (省略) =================== TEST RESULT SUMMARY ------------- Exts skipped : 45 Exts tested : 27 ------------- Number of tests : 16033 11240 Tests skipped : 4793 ( 29.9%) -------- Tests warned : 0 ( 0.0%) ( 0.0%) Tests failed : 4 ( 0.0%) ( 0.0%) Expected fail : 31 ( 0.2%) ( 0.3%) Tests passed : 11205 ( 69.9%) ( 99.7%) ===================

Slide 9

Slide 9 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon テストスクリプト phpt 9 PHP内部およびQAチームがPHPの機能をテストするために使用されるスクリプト 新機能追加時に書かれ、既存のバグを検知する回帰テストの役割も兼ねる $ find . -name 'tests' -type d ./php-src/tests PHP内部のテスト ./php-src/Zend/tests Zend(PHPコア部分)のテスト ./php-src/ext/*/tests PHP Extensionのテスト ./php-src/sapi/*/tests SAPIのテスト $ find . -name '*.phpt' | wc -l 16033 ※ 2020年12月11日段階の筆者環境でのphptファイル件数

Slide 10

Slide 10 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon PHPの関数とphptテストの一覧 10 「この関数のテストファイルどこかな?」を探すときにちょっと便利 http://gcov.php.net/viewer.php?version=PHP_HEAD&func=tested_functions

Slide 11

Slide 11 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon phptファイルの読み方 --TEST-- テストタイトル --FILE-- テストの入力となるPHPスクリプト --EXPECT-- テスト結果の期待値 (ex. var_dump, echo) ※ その他のファイルセクション仕様 https://qa.php.net/phpt_details.php 11 https://github.com/php/php-src/blob/0e60b812c05ed5e3704ab6f31f29040040c3edd7/ext/standard/tests/ strings/strtr.phpt#L2 php-src/ext/standard/tests/strings/strtr.phpt

Slide 12

Slide 12 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon phptファイルの「命名規則」 phptファイルは命名規則が設定されている。 現実としてはすべてがこの規則に沿っているわけではないが、 どういった種類のテストがあるか傾向を知れる。 ● bug.phpt : Tests for bugs ● _basic.phpt : Tests for a function's basic behaviour ● _error.phpt : Tests for a function's error behaviour ● _variation.phpt : Tests for variations in a function's behaviour ● .phpt : General tests for extensions https://qa.php.net/write-test.php#naming-conventions 12

Slide 13

Slide 13 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon bug.phpt bugs.php.net に起票されたbugidに対応するテストケース $ find . -name 'bug*.phpt' | wc -l 3957 13 https://github.com/php/php-src/blob/7aacc705d038 87c64a90489e367f4c40b46aa3c2/tests/basic/bug54 514.phpt#L2 ex. bug54515.phpt https://bugs.php.net/bug. php?id=54514

Slide 14

Slide 14 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon _basic.phpt 関数に対するシンプルなパターンのテストケースが記述さ れる $ find . -name '*_basic.phpt' | wc -l 892 ex. ext/standard/tests/assert/assert_basic.phpt → assert実行時にcallbackが走るか 14 https://github.com/php/php-src/blob/7aacc705d03887c64a90489e367f 4c40b46aa3c2/ext/standard/tests/assert/assert_basic.phpt#L2

Slide 15

Slide 15 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon _error.phpt 関数に対するエラーのテストケースが記述される $ find . -name '*_error.phpt' | wc -l 350 ex. Zend/tests/generators/errors/count_error.phpt → Generatorを count() に渡した際にエラーになるか 15 https://github.com/php/php-src/blob/2ee7e2982f5609ca6c3837c0b93ba9c5e89f84cb/Zend/tests/generators/e rrors/count_error.phpt#L2

Slide 16

Slide 16 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon _variation.phpt 16 境界条件をテストするといったバリエーションを扱いたい 場合のテスト $ find . -name '*_variation.phpt' | wc -l 74 ex. ext/standard/tests/math/sin_variation.phpt → 正弦を求めるsin関数のバリエーションテスト https://github.com/php/php-src/blob/0c6d06ecfa8f75f5afc4daf852a76c90 5b672b25/ext/standard/tests/math/sin_variation.phpt#L2

Slide 17

Slide 17 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon .phpt 17 PHP Extensionの一般的なテストをする際のテ ストです。 ex. ext/dba/tests/dba003.phpt → Database Extensionのテスト https://github.com/php/php-src/blob/c5401854fcea27ff9aabfd0682ff4d81 bbb3c888/ext/dba/tests/dba003.phpt#L2

Slide 18

Slide 18 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 実際のphptファイル 前述したとおりすべてがそのphptファイルの規則というわけではない。 しかし、ファイル名から命名規則のどれに該当するかでおおまかに内容が類推できる。 ex. Named Arguments機能のphptテストファイル $ tree -L 1 Zend/tests/named_params/ Zend/tests/named_params/ ├── __call.phpt // Named Argumentsが __call で機能してるか ├── assert.phpt // assertをNamed Argumentsとともに ├── basic.phpt // _basicの命名規則に該当する内容 ├── cannot_pass_by_ref.phpt // エラーケース(参照渡し) ├── duplicate_param.phpt // エラーケース(同一引数に重複して渡した) └── // (省略) 18

Slide 19

Slide 19 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 特定のテストを実行したい場合(make test) TESTSオプションに実行したいテストファイル名を指定する ディレクトリ以下全ケースの場合は/* (ex. Zend/tests/named_params/*) $ make test TESTS='--show-diff Zend/tests/named_params/duplicate_param.phpt' Running selected tests. PASS Duplicate param [Zend/tests/named_params/duplicate_param.phpt] ============= Number of tests : 1 1 ...(省略) Tests passed : 1 (100.0%) (100.0%) 19 See also 『PHP extensionのmake testに関するTIPS - @hnw』 (https://qiita.com/hnw/items/f70e52eaa065ae573668#teststests002phpt)

Slide 20

Slide 20 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 失敗時の差分をみる(--show-diff) TESTSオプションに--show-diffを指定することで失敗時の差分が表示される $ make test TESTS='--show-diff Zend/tests/named_params/duplicate_param.phpt' Running selected tests. TEST 1/1 [Zend/tests/named_params/duplicate_param.phpt] ========DIFF======== 001+ 2 Named parameter $a overwrites previous argument 001- Named parameter $a overwrites previous argument ========DONE======== FAIL Duplicate param [Zend/tests/named_params/duplicate_param.phpt] 20 See also 『PHP extensionのmake testに関するTIPS - @hnw』 (https://qiita.com/hnw/items/f70e52eaa065ae573668#teststests002phpt)

Slide 21

Slide 21 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon phpt を読むことで得られるもの PHP Userは、php.netを閲覧することで言語機能 の使い方を知れるが、主に正常系と限定的であ る。 PHP自体・コアに対するテストコードである phpt を読むことで、正常ケース以外も境界値やエラー ケースの仕様を把握できる。 Cに不慣れであっても読みやすく、php-srcのコー ドを読み始める第一歩となる。 21

Slide 22

Slide 22 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 読んでいくPHP8 New Features 22 1 2 3 Named Arguments 4 5 6 Constructor property promotion Attributes Union Types Match expression Nullsafe operator

Slide 23

Slide 23 text

#phpcon © 2012-2020 BASE, Inc. 23 - PHP8 New Feature - Named Arguments

Slide 24

Slide 24 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon Named Arguments 引数に名前をつけて渡すことが出来る RFC: https://wiki.php.net/rfc/named_params PR: https://github.com/php/php-src/pull/5357 (主な)phpt files: Zend/test/named_params/* (30 files) 24

Slide 25

Slide 25 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon Named Arguments [Merits] 1. 引数が多い場合に順番を気にしなくてもよくなる 2. htmlspecialchars()のようにデフォルト値が多い引数の場合に記述が簡潔になる 3. 意味がわかりにくい引数を渡す場合のコードの自己記述性の向上 25

Slide 26

Slide 26 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon $ tree -L 1 Zend/test/named_params ├── __call.phpt ├── basic.phpt ├── duplicate_param.phpt ├── missing_param.phpt ├── runtime_cache_init.phpt ├── undef_var.phpt ├── unknown_named_param.phpt ├── unpack.phpt ├── unpack_and_named_1.phpt ├── ├── (省略) └── variadic.phpt 26 主なphptテストファイル一覧

Slide 27

Slide 27 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 基本的なテストケース 27 Zend/tests/named_params/basic.phpt [テストケースから読み取れる仕様] ● “positional argument”と”Named Argument”の併用が 可能

Slide 28

Slide 28 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 未定義変数を引数に渡した場合 28 Zend/tests/named_params/undef_var.phpt [テストケースから読み取れる仕様] ● 未定義変数を渡した場合Warningとなり当該 箇所はNULLが値として設定される https://github.com/php/php-src/blob/6992c38ecc512a00b80af64d5422470 dd1e74c36/Zend/tests/named_params/undef_var.phpt#L2

Slide 29

Slide 29 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 重複して2回渡した場合 29 Zend/tests/named_params/undef_var.phpt [テストケースから読み取れる仕様] ● 重複して2回同じ引数に値を渡した場合例外Error が発生 ○ Named parameter $%s overwrites previous argument test(a: 1 a: 2); https://github.com/php/php-src/blob/d92229d8c78aac25925284e23a a7903dca9ed005/Zend/tests/named_params/duplicate_param.phpt#L2

Slide 30

Slide 30 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 30 Deep Dive into PHP Internal [テストケースから内部実装を覗く] ● 重複して2回同じ引数に値を渡した 場合例外Errorが発生 ○ Named parameter $%s overwrites previous argument これはどのような実装によって実現さ れているのか?

Slide 31

Slide 31 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 重複して2回渡した場合のエラー発生コード “Named parameter $%s overwrites previous argument”でgrepして見つける 31 zend_execute.c https://github.com/php/php-src/blob/77325c4448cff9d031b86c39493 2acb072e99bfe/Zend/zend_execute.c#L4431

Slide 32

Slide 32 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon そもそもZend Engineとは [Zend VM] PHPの中間コードを実行する仮想CPU実装 オペコード列を実行する機能 See also: @hnwさん『Zend VMにおける例外の実装』 (https://www.slideshare.net/hnw/zend-vm-227589843) 32

Slide 33

Slide 33 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon PHPコード実行サイクル内のzend_execute 33 zend_execute.c See also: julien pauliさん『Quick tour of PHP from inside』 (https://www.slideshare.net/jpauli/quick-tour-of-php-from-inside) ● Startup: メモリアロケーション ● zend_compile_file(): コンパイル ○ (字句解析・構文解析・OPCode生成) ● zend_execute(): OPCode実行 ● Shutdown: メモリ解放 →今回のエラーハンドリングはzend_executeフェーズ

Slide 34

Slide 34 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 34 Cコードをいじってみてテストで確かめる ちょっとCコードを微修正してテストを走らせるとCコードレベルで理解する取っ掛か りになる $ make test TESTS='--show-diff Zend/tests/named_params/duplicate_param.phpt' ========DIFF======== 001+ 2 Named parameter $a overwrites previous argument 001- Named parameter $a overwrites previous argument ========DONE======== FAIL Duplicate param [Zend/tests/named_params/duplicate_param.phpt]

Slide 35

Slide 35 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon phpスクリプトとCコードの対応 35 Zend/tests/named_params/duplicate_param.phpt Zend/zend_execute.c Cコードのエラーメッセージを 区別がつくように修正して テストを再実行した

Slide 36

Slide 36 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon エラーケースの仕様をphptから理解する Named Argumentsについてドキュメントでは詳 細記載されていないエラー系の仕様をテストコー ドを通じて知った。 「こういう時エラーになるのかな?」 「言語機能として期待した振る舞いなのか?」 PHP内部実装について紐解いていくきっかけとな る。内部のCコードとの対応付けを部分的に理解し ていくことを積み重ねる 36

Slide 37

Slide 37 text

#phpcon © 2012-2020 BASE, Inc. 37 - PHP8 New Feature - Constructor property promotion

Slide 38

Slide 38 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon Constructor property promotion Constructorの引数にアクセス修飾子を足す ことでプロパティ宣言と対応させる RFC: https://wiki.php.net/rfc/constructor_p romotion PR: https://github.com/php/php-src/pull/5 291 (主な)phpt files: Zend/tests/ctor_*.phpt (16 files) 38

Slide 39

Slide 39 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon Constructor property promotion すべてのプロパティ属性に使用しなくてもいい。Constructorで渡す必要のない内部管理の 状態などと使い分け。 39

Slide 40

Slide 40 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 主なphptテストファイル一覧 $ ls Zend/tests/ctor* ctor_promotion_abstract.phpt ctor_promotion_additional_modifiers.phpt ctor_promotion_attributes.phpt ctor_promotion_basic.phpt ctor_promotion_by_ref.phpt ctor_promotion_callable_type.phpt ctor_promotion_defaults.phpt ctor_promotion_free_function.phpt ctor_promotion_interface.phpt ctor_promotion_mixing.phpt ctor_promotion_not_a_ctor.phpt 40 ctor_promotion_null_default.phpt ctor_promotion_repeated_prop.phpt ctor_promotion_trait.phpt ctor_promotion_untyped_default.phpt ctor_promotion_variadic.phpt

Slide 41

Slide 41 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 基本的なテストケース 41 Zend/tests/ctor_promotion_basic.phpt [テストケースから読み取れる仕様] ● Constructor property promotionの基本的な使い方 https://github.com/php/php-src/blob/064b4644484d38e9dce40ae f7e8e0e8190e9d863/Zend/tests/ctor_promotion_basic.phpt#L2

Slide 42

Slide 42 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon abstractクラスでの利用 42 [テストケースから読み取れる仕様] ● abstractクラスで使用した場合はFatal Error ※ RFC内で制約として記載されてはいる https://github.com/php/php-src/blob/064b4644484d38e9dce40aef7e8e0e8190e9d863/Zend/tests/ctor_promotio n_abstract.phpt#L2 Zend/tests/ctor_promotion_abstract.phpt

Slide 43

Slide 43 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon Callable typeとの併用 43 [テストケースから読み取れる仕様] ● callableタイプはサポートしていない RFC内で制約として記載されてはいるが、 クラスのproperty typeとしてcallableがサ ポートされていないため https://github.com/php/php-src/blob/064b4644484d38e9dce40aef7e8e0e8190e9d863/Zend/tests/ctor_promotio n_callable_type.phpt#L2 Zend/tests/ctor_promotion_callable_type.phpt

Slide 44

Slide 44 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon Trait内で使う 44 [テストケースから読み取れる仕様] ● trait内で使用可能 RFCにもしれっと一行書いてるくらいの内容 While unusual, promoted parameters may occur inside trait constructors. https://github.com/php/php-src/blob/064b4644484d38e9dce40aef7e8e0e8190e9d863/Zend/tests/ctor_promotio n_trait.phpt#L2 Zend/tests/ctor_promotion_trait.phpt

Slide 45

Slide 45 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon nullable typeでない型にnullを指定した 45 [テストケースから読み取れる仕様] ● nullable typeではないプロパティのデ フォルト値にnull指定不可 https://github.com/php/php-src/blob/064b4644484d38e9dce40aef7e8e0e8190e9d863/Zend/tests/ctor_promotio n_null_default.phpt#L2 Zend/tests/ctor_promotion_null_default.phpt

Slide 46

Slide 46 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon ...$var(variadic param)の使用 46 [テストケースから読み取れる仕様] ● variadic param(...$var)は使用不可 https://github.com/php/php-src/blob/064b4644484d38e9dce40aef7e8e0e8190e9d863/Zend/tests/ctor_promotio n_variadic.phpt#L2 Zend/tests/ctor_promotion_variadic.phpt

Slide 47

Slide 47 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 微妙なユースケースについてphptで理解する Constructor property promotionについてRFC をじっくり読まないと気が付きにくい微妙なユー スケース仕様をphptを通じて知った。 「abstract classはいけるんだっけ?」 「callable typeだと使えないかな?」 「classはいけるけどtraitはどうだっけ?」 47

Slide 48

Slide 48 text

#phpcon © 2012-2020 BASE, Inc. 48 - PHP8 New Feature - Attributes

Slide 49

Slide 49 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon Attributes 49 クラス・プロパティ...etcも構造化・構文的な メタデータとしての属性定義 Annotations in Java Attributes in C#, C++, Rust, Hack Decorators in Python, Javascript RFC: https://wiki.php.net/rfc/attributes_v2 PR: https://github.com/php/php-src/pull/5394 (主な)phpt files: Zend/tests/attributes/* (33 files)

Slide 50

Slide 50 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 主なphptテストファイル一覧 $ ls Zend/tests/attributes/ 001_placement.phpt 002_rfcexample.phpt 003_ast_nodes.phpt 004_name_resolution.phpt 005_objects.phpt 006_filter.phpt 007_self_reflect_attribute.phpt 008_wrong_attribution.phpt 009_doctrine_annotations_example.phpt 010_unsupported_const_expression.phpt 011_inheritance.phpt (省略) 50 029_reflect_internal_symbols.phpt 030_strict_types.inc 030_strict_types.phpt 031_backtrace.phpt 032_attribute_validation_scope.phpt

Slide 51

Slide 51 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon Named Argumentsとの組み合わせ 51 Zend/tests/named_params/attribute s.phpt [テストケースから読み取れる仕様] ● “Attribute”に対しても”Named Argument”が使用可能 #[MyAttribute('A', c: 'C')] class Test1 {} https://github.com/php/php-src/blob/8b37c1e993f17345312a76a239b77ae137d3f8e8/Zend/tests/named_params /attributes.phpt#L2

Slide 52

Slide 52 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon Constructor property promotionと組み合わせ 52 [テストケースから読み取れる仕様] ● Constructor property promotionで作ら れるプロパティにもAttribute設定可能 public function __construct( #[NonNegative] public int $num, ) {} https://github.com/php/php-src/blob/8b37c1e993f17345312a76a239b77ae137d3f8e8/Zend/tests/ctor_promotio n_attributes.phpt#L2 Zend/tests/ctor_promotion_attributes.phpt

Slide 53

Slide 53 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon AttributeのGroup化 53 [テストケースから読み取れる仕様] ● class/functionに対して複数のAttribute を設定 https://github.com/php/php-src/blob/8b37c1e993f17345312a76a239b77ae137d3f8e8/Zend/tests/attributes/02 8_grouped.phpt#L2 Zend/tests/attributes/028_grouped.phpt

Slide 54

Slide 54 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon Doctrine-likeなAttribute使用 54 [テストケースから読み取れる仕様] ● Attribute実装時にコミッターがDoctrine のようなユースケースを想定したこと 当機能コミッターの@beberleiがDoctrineコ アコミッターである背景が垣間見える (個人の感想です) https://github.com/php/php-src/blob/8b37c1e993f17345312a76a239b77ae137d3f8e8/Zend/tests/attributes/00 9_doctrine_annotations_example.phpt#L2 Zend/tests/attributes/009_doctrine_ann otations_example.phpt

Slide 55

Slide 55 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 機能の組み合わせ可能性をphptで理解する 各機能単体では気が付かないかもしれない新機能 の組み合わせの仕様をphptを通じて知った。 「Attributes && Named Argument」 「Attributes && Constructor property promotion」 テストケースからコミッターの実装時の考慮事項 ・背景が少し浮かび上がって見えた。 55

Slide 56

Slide 56 text

#phpcon © 2012-2020 BASE, Inc. 56 - PHP8 New Feature - Union Types

Slide 57

Slide 57 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon Union Types 複数の異なる型の値を受け付ける型宣言 RFC: https://wiki.php.net/rfc/union_types_ v2 PR: https://github.com/php/php-src/pull/4 838 (主な)phpt files: Zend/tests/type_declarations/union_ty pes/* (30 files) 57

Slide 58

Slide 58 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon $ tree -L 2 Zend/tests/type_declarations/union_types/ ├── generator_return_containing_extra_types.phpt ├── (省略) ├── redundant_types │ ├── (省略) │ └── object_and_static.phpt ├── standalone_false.phpt ├── (省略) ├── variance │ ├── (省略) │ └── valid.phpt └── void_with_class.phpt 58 主なphptテストファイル一覧

Slide 59

Slide 59 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon null単体で使用した場合 59 Zend/tests/type_declarations/union_ types/standalone_null.phpt [テストケースから読み取れる仕様] ● Nullable union typesは仕様としてある が、null単体の使用は不可 php.netにも注意書きがある仕様 https://www.php.net/manual/en/language.types.declarations.php#la nguage.types.declarations.union https://github.com/php/php-src/blob/999e32b65a8a4bb59e27e538fa68ffae4b99d863/Zend/tests/type_declarati ons/union_types/standalone_null.phpt#L2

Slide 60

Slide 60 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon false単体で使用した場合 60 Zend/tests/type_declarations/union_ types/standalone_false.phpt [テストケースから読み取れる仕様] ● false pseudo-typesは仕様としてある が、false単体の使用は不可 all of false, false|null and ?false are not permitted (php.net) https://github.com/php/php-src/blob/999e32b65a8a4bb59e27e538fa68ffae4b99d863/Zend/tests/type_declarati ons/union_types/standalone_false.phpt#L2

Slide 61

Slide 61 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon voidをUnionTypeで使用した場合 61 Zend/tests/type_declarations/union_ types/void_with_class.phpt [テストケースから読み取れる仕様] ● voidはUnionTypeでは使用不可 RFCでは言及されている内容 The void type can never be part of a union. As such, types like T|void are illegal in all positions, including return types. https://github.com/php/php-src/blob/999e32b65a8a4bb59e27e538fa68ffae4b99d863/Zend/tests/type_declarati ons/union_types/void_with_class.phpt#L2

Slide 62

Slide 62 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon strictモード有効・無効時の挙動 62 https://github.com/php/php-src/blob/999e32b65a8a4bb59e27e538fa68ffae4b99d863/Zend/tests/type_declarati ons/union_types/type_checking_strict.phpt#L2 https://github.com/php/php-src/blob/999e32b65a8a4bb59e27e538fa68ffae4b99d863/Zend/tests/type_declarati ons/union_types/type_checking_weak.phpt#L2 [type_checking_weak.phpt - 無効] Type int|string|null: 42 => 42 42.0 => 42 INF => "INF" "42" => "42" (省略) true => 1 false => 0 null => null [] => Type Error new stdClass => Type Error new WithToString => "__toString()" [type_checking_strict.phpt - 有効] Type int|string|null: 42 => 42 42.0 => Type Error INF => Type Error "42" => "42" (省略) true => Type Error false => Type Error null => null [] => Type Error new stdClass => Type Error new WithToString => Type Error

Slide 63

Slide 63 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon バリエーションに伴う仕様をphptで理解する Union Typesを用いるバリエーションとそれに伴 う仕様についてphptから知った。 「Union Typesで使用不可な『型』はなにか」 「strictモード有効にした場合int|string|nullの 引数に対してどのような挙動となるか」 63

Slide 64

Slide 64 text

#phpcon © 2012-2020 BASE, Inc. 64 - PHP8 New Feature - Match expression

Slide 65

Slide 65 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon Match expression match式の導入、switch文に類似するが値を 返すため、直接 return したりできる RFC: https://wiki.php.net/rfc/match_expres sion_v2 PR: https://github.com/php/php-src/pull/5 371 phpt files: Zend/tests/match/* (24 files) 65

Slide 66

Slide 66 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon $ ls Zend/tests/match/ 001.phpt 002.phpt 003.phpt 004.phpt 005.phpt 006.phpt 007.phpt 008.phpt 009.phpt 011.phpt 012.phpt 017.phpt 66 主なphptテストファイル一覧 023.phpt 024.phpt 027.phpt 028.phpt 029.phpt 030.phpt 037.phpt 038.phpt 039.phpt 040.phpt 041.phpt 042.phpt

Slide 67

Slide 67 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 基本的なユースケース 67 Zend/tests/match/001.phpt [テストケースから読み取れる仕様] ● match式をreturnに利用する基本的な利用シーン https://github.com/php/php-src/blob/9fa1d1330138ac424f990ff03e62721 120aaaec3/Zend/tests/match/001.phpt#L2

Slide 68

Slide 68 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 条件判定を組み合わせる場合 68 Zend/tests/match/004.phpt [テストケースから読み取れる仕様] ● match式内で条件を書く場合の想定コード https://github.com/php/php-src/blob/9fa1d1330138ac424f990ff03e62721 120aaaec3/Zend/tests/match/004.phpt#L2

Slide 69

Slide 69 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon match式内に該当するケースが無い場合 69 Zend/tests/match/007.phpt [テストケースから読み取れる仕様] ● match式内でケースに該当するものがない場合 Fatal errorが発生する https://github.com/php/php-src/blob/9fa1d1330138ac424f990ff03e62721 120aaaec3/Zend/tests/match/007.phpt#L2

Slide 70

Slide 70 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 1ケースに複数条件を指定する 70 Zend/tests/match/008.phpt [テストケースから読み取れる仕様] ● match式内で複数条件を指定可能 https://github.com/php/php-src/blob/9fa1d1330138ac424f990ff03e62721 120aaaec3/Zend/tests/match/008.phpt#L2

Slide 71

Slide 71 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 条件リストの最後もコンマ(,) 71 Zend/tests/match/041.phpt [テストケースから読み取れる仕様] ● 条件リストの最後もコンマ(,)を指定している 場合 https://github.com/php/php-src/blob/9fa1d1330138ac424f990ff03e62721 120aaaec3/Zend/tests/match/041.phpt#L2

Slide 72

Slide 72 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 細かい挙動をphptで理解する Match Expressionを用いる際の細かい仕様につい てphptから知った。 「matchの条件リストの最後コンマ(,)入れれる の?」 「条件リストに合致しなかった場合はどういう振 る舞いになる?」 72

Slide 73

Slide 73 text

#phpcon © 2012-2020 BASE, Inc. 73 - PHP8 New Feature - Nullsafe operator

Slide 74

Slide 74 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon Nullsafe operator nullチェックを入念にしていたものは、 nullsafe演算子によってチェーン実行できる RFC: https://wiki.php.net/rfc/nullsafe_oper ator PR: https://github.com/php/php-src/pull/5 619 phpt files: Zend/tests/nullsafe_operator/* (39 files) 74

Slide 75

Slide 75 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon $ ls Zend/tests/nullsafe_operator/ 001.phpt 002.phpt 003.phpt 004.phpt 005.phpt 006.phpt 007.phpt 008.phpt 009.phpt 010.phpt 011.phpt (省略) 75 主なphptテストファイル一覧 029.phpt 030.phpt 031.phpt 032.phpt 033.phpt 034.phpt 035.phpt 036.phpt 037.phpt 038.phpt 039.phpt

Slide 76

Slide 76 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon property書き込みシーンでの利用 76 Zend/tests/nullsafe_operator/004.phpt [テストケースから読み取れる仕様] ● プロパティの書き込み操作に対しては使用不可 https://github.com/php/php-src/blob/9fa1d1330138ac424f990ff03e62721 120aaaec3/Zend/tests/nullsafe_operator/004.phpt#L2

Slide 77

Slide 77 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon Nullsafe operatorを怪しげなコード 77 Zend/tests/nullsafe_operator/041.phpt [テストケースから読み取れる仕様] ● ちょっとテクい事をしようとするPHPユーザー を想定したテストケースがある ● このケースでは undefined variable Warning が発生する https://github.com/php/php-src/blob/9fa1d1330138ac424f990ff03e62721 120aaaec3/Zend/tests/nullsafe_operator/041.phpt#L2

Slide 78

Slide 78 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 微妙なユーザーコードの動作をphptで理解する Nullsafe operatorを用いる際のPHPユーザーとし てやってしまいそうな微妙なコードがどう動くか についてphptから知った。 「propertyの書き込み時に使っちゃうとどうな る?」 78

Slide 79

Slide 79 text

#phpcon © 2012-2020 BASE, Inc. 79 Summary

Slide 80

Slide 80 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon phpt を読むことで得られたもの phptを読むことで次の内容を理解できた。 - 言語としてのエラーケース - 微妙なユースケースの仕様 - 複数機能の組み合わせ - 開発者の実装背景 - Cコードリーディングの出発点 ドキュメントを読むだけではわからない・気が付 かない内容を知れる。 80

Slide 81

Slide 81 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 81 PHPの新機能を見る際はphptと共に 当発表のようにPHPのPull Requestを覗い て、phptファイルを探してみてください。 「こういう書き方出来るようになったんだ〜」 というPHPユーザーの視点から、 「こういう振る舞いをこのパターンに気をつけ て実装したんだ」というPHP開発者の視点に、 少しだけ近づける感覚が味わえるはずです。

Slide 82

Slide 82 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 具体的な一歩目のガイド資料 82 PHP Advent Calendar DAY 5 ソースコード(php-src)からPHPを ビルドする流れと仕組みを手を動かしながら理解する https://zenn.dev/hgsgtk/articles/fb9af8bfc64ec37bce2d PHP Advent Calendar DAY 9 PHP8の新機能 Named Arguments を php-srcのテストコードから読む https://zenn.dev/hgsgtk/articles/461f3e8c1d81df

Slide 83

Slide 83 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon PHP Internalを知る参考資料 @hnwさん『Zend VMにおける例外の実装』 - 2020/02/11 (https://www.slideshare.net/hnw/zend-vm-227589843) 『Php internal architecture』 - 2016/10/19 (https://www.slideshare.net/auroraeosrose/php-internal-architecture) @sji_chさん『PHP による hello world 入門』 - 2015/06/18 (http://tech.respect-pal.jp/php-helloworld/) julien pauliさん『Quick tour of PHP from inside』 - 2012/06/07 (https://www.slideshare.net/jpauli/quick-tour-of-php-from-inside)

Slide 84

Slide 84 text

#phpcon © 2012-2020 BASE, Inc. 84 Bonus

Slide 85

Slide 85 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 85 Deep Dive into PHP Internal [テストケースから内部実装を覗く] ● Match expressionでは、Uncaught UnhandledMatchError: Unhandled match value of type %s in %s というエラーの発生があ りうる これに対応する実装はどうなっているのかな? Zend/tests/match/007.phpt

Slide 86

Slide 86 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon https://github.com/php/php-src/blob/841b00f641d448f 037c69f0910ec4fb54cd64b20/Zend/zend_vm_execute.h# L13836 https://github.com/php/php-src/blob/841b00f641d448f 037c69f0910ec4fb54cd64b20/Zend/zend_vm_execute.h# L13836 Unhandled match value of type %s in %s “Unhandled match value of type”でgrepして見つける(3箇所ある) 86 zend_vm_def.h zend_vm_execute.h

Slide 87

Slide 87 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon 87 Cコードをいじってみてテストで確かめる ちょっとCコードを微修正してテストを走らせるとCコードレベルで理解する取っ掛か りになる $ make test TESTS='--show-diff Zend/tests/match/006.phpt' ========DIFF======== 001+ Fatal error: Uncaught UnhandledMatchError: b Unhandled match value of type bool in /Users/user/src/github.com/php/php-src/Zend/tests/match/006.php:3 001- Fatal error: Uncaught UnhandledMatchError: Unhandled match value of type bool in %s ========DONE======== FAIL Match expression with no cases [Zend/tests/match/006.phpt]

Slide 88

Slide 88 text

© 2012-2019 BASE, Inc. © 2012-2020 BASE, Inc. #phpcon https://github.com/php/php-src/blob/841b00f641d448f 037c69f0910ec4fb54cd64b20/Zend/zend_vm_execute.h# L13836 https://github.com/php/php-src/blob/841b00f641d448f 037c69f0910ec4fb54cd64b20/Zend/zend_vm_execute.h# L13836 同じエラーだが実装が違う 条件指定なし(006)・条件指定あるがマッチしない(007/037)で異なる 88 zend_vm_def.h zend_vm_execute.h

Slide 89

Slide 89 text

#phpcon © 2012-2020 BASE, Inc. 89 #track5-4-a-phpt