Advertisement
Advertisement

More Related Content

Slideshows for you(20)

Advertisement

モダン PHP テクニック 12 選 ―PsalmとPHP 8.1で今はこんなこともできる!―

  1. モダンPHP テクニック12 選 ―PsalmとPHP 8.1で今はこんなこともできる!― 五十嵐進士(sji)
  2. 自己紹介 sji / sj-i / @sji_ch SNS 上でのアイコンはGitHub が自 動生成した奴
  3. 生まれも育ちも仙台
  4. PHP カンファレンス仙台とかやった
  5. ふつうのサラリーマン 株式会社インフィニットループ仙台 支社所属 スマホゲーのサーバサイドプログラ マ
  6. その他 一昨年娘ができた かわいい WEB+DB PRESS の現PHP 連載担当 12/24(金)発売の126号はPHP 8.1 の紹介
  7. Agenda PHP の今について モダンなPHP のテクニック12 個くらい紹介
  8. PHP の今
  9. PHP 8.1 が出た 型の表現力が強化され、扱いも更に厳格化 readonly never 交差型 Enum、などなど Fiber で非同期処理が更に便利に 汎用言語化が更に進む
  10. 「ゆるふわPHP が汎用言語ですって?」
  11. お前らPHPの型がゆるふわゆるふわ言うけど な、PHPなら型を宣言した値が勝手にnullに なったりしねーし 一部の言語、ここで血反吐をはき倒れる
  12. ていうか、今のPHP はもうそんなにゆるふわ でもないんです!
  13. 大静的型解析時代 型情報を使う静的解析ツールが隆盛 PHPStan Psalm Phan 静的解析ツールは言語の弱点を補うものとなりがり PHP はゆるふわな型が弱点 ガチガチな静的解析ツールで補う
  14. JetBrains の調査いわく 「どんな品質ツールを使っていますか」 PHPStan Psalm Phan 計 2019 9% 1% 5% 15% 2020 11% 3% 2% 16% 2021 18% 9% 2% 29% 「静的解析ツールを使ってますか」 はい いいえ なにそれ 2021 33% 38% 28% https://www.jetbrains.com/lp/devecosystem-2019/php/ https://www.jetbrains.com/lp/devecosystem-2020/php/ https://www.jetbrains.com/lp/devecosystem-2021/php/
  15. 静的型解析の何が嬉しい? 実行しなくてもバグに気づける PHP の言語自体を超えた型の表現力 エディタの補完やナビゲーションの強化
  16. Psalm Vimeo で使われている静的解析ツール 先日原作者は卒業した、が、今も活発に開発 比較的型の表現力が高い
  17. ここから12 のワザを大紹介
  18. 1. クラスをボコボコ生やす PHP でデータや処理に型をつける 最強の手段 言語機能やツールの恩恵を最大限に 得られる Constructor Property Promotion 最高 ちょっとした処理や値の表現でもク ラスを定義 class SomeThing { public function __construct( public int $id, public string $name, public Dependency $obj, ) { } }
  19. 2. DI コンテナでautowiring 多くのDI コンテナで利用可能 Laravel のContainer やPHP-DI など コンストラクタへ依存クラスを並べ ていくだけ 自分でnew するのはVO とかテスト とかごく一部に Laravel でもFacade よりDI // DI コンテナが勝手に依存先を生成 public function __construct( public readonly Dependency1 $obj1 public readonly Dependency2 $obj2 ) { }
  20. 3. 型は早めにつける @varより@param どんどん呼び出し元へ追いやる 結果コントローラなどリクエス トの入口のほうに 誤りは早く検知できるほどよい リリースの後より前 テスト環境よりCI CI より手元のエディタ リクエスト処理の後半より前半 // こっちより public function f(array $items) { /** @var Item $item */ foreach ($items as $item) { } } // こっち /** @param Item[] $items */ public function f(array $items) { foreach ($items as $item) { } }
  21. 4. 静的解析可能な入力値検査 一部ライブラリで静的型検査フレ ンドリーに入力値の検査やキャス トが可能 webmozart/assert azjezz/psl cuyz/valinor OpenAPI やJSON scheme などIDL からのクラス自動生成も有効 // webmozart/assert の例 Assert::integer($id); // $id はこの先 int 扱い // azjezz/psl の例 $spec = Typeshape([ 'id' => Typeint(), 'name' => Typestring(), 'age' => Typeoptional( Typeint() ) ]); // $input をバリデーションしつつキャスト $input = $spec->coerce($_POST['input'] // $input はこの先で↓の扱い // array{id: int, name: string, age?:
  22. 5. 静的解析可能なconfig 連想配列のかわりにValueObject を 使う DI コンテナに登録して取り出すの もよい 型の保護や補完が効く 名前付き引数を利用 順番の意識が不要に 設定項目の追加や削除なども静 的に検知可能 return new DatabaseConfiguration( driver: new MySQLDriverConfiguration host: 'localhost', port: 3306, db_name: 'test_db', username: 'test', password: 'mogera', ), )
  23. 6. 静的解析可能なCollection を使う 最近illuminate/collections がジェネ リクスに対応 doctrine/collections も以前からジェ ネリクスに対応 PhpStorm もそれらのジェネリクス にある程度対応 あかん場合は@varと@psalm- ignore-varを併用 /** @param Collection<User> $users */ public function f(Collection $users) foreach ($users as $user) { // $user は User として型推論 } }
  24. 7. 静的解析可能なOrm を使う doctrine/orm cycle/orm も2 系以降でいくらか eloquent はlarave-pluginやアノテー ション生成が必要 Orm を自作してでも静的解析に対 応させる cuyz/valinor など既存hydrator の利用も可 // $user は User|null と推論される $user = $entityManager ->getRepository(User::class) ->find(1);
  25. 8. 静的解析可能な配列を使う psalm の型アノテーションでは配 列のキーや値の型が指定可能 「連番の数値添字が0から順に並ん だ配列」(list)も指定可能 non-empty-array やnon-empty-list もある Shapes で構造体的な配列やタプル も宣言できる /** @param array<ItemType> $p */ /** @param array<int, ItemType> $p */ /** @param list<ItemType> $p */ /** @param non-empty-array<ItemType> $p /** * @param array{ * id: int, * name: string * } $p */ /** @param array{int, string} */
  26. 9. 静的解析可能な分岐網羅を使う PHP 8.0 で入ったmatch は分岐網羅 検査がある 想定してない値が来ると例外 Psalm はdefault のないmatch や switch で静的に分岐網羅を検査でき る場合がある 値のUnion やEnum をうまく使う 無闇に可変関数呼び出しなどの動的 処理は使わない、愚直に分岐を書く enum Result { case Succeed; case Failed; } // ResultStatus::Failed を網羅してないの // 静的解析段階でエラーになる function f(Result $status): int { return match ($status) { ResultStatus::Succeed => 1, }; }
  27. 10. 書き込み、状態を減らす PHP 8.1 でreadonly が追加 Psalm でも@immutable や@pure などがある なるべく完全コンストラクタ+不変 状態を持たない= 各生成時点で全情 報が必要 小さなクラスが増え神クラス化 も防ぎやすくなる class ReadOnlyClass { public function __construct( public readonly int $id, public readonly string $name, ) { } } /** @psalm-immutable */ class ImmutableClass { public function __construct( public int $id, public string $name, ) { } }
  28. 11. なるべく多くを型で表現 ValueObject 、DTO みたいなのをバ ンバン作る ID の種類ごとに異なるクラスを定 義する ジェネリクスを使ってもよい 実クラスを定義しなくとも型 タグを使える ちかぢか同僚が会社のブロ グで紹介するかも trait ItemId { public function __construct( public readonly int $value, ) { } } class ConsumableItemId {use ItemId;} class EquipmentItemId {use ItemId;} class Consumableuser { public function useItem( ConsumableItemId $item_id ): void { } }
  29. 12. Package-By-Feature (に寄せる) UserController UserModel UserView ItemController ItemModel ItemView CurrencyController CurrencyModel CurrencyView User Item Currency Package By Feature UserModel ItemModel CurrencyModel UserController ItemController CurrencyController UserView ItemView CurrencyView Model Controller View Package By Layer PBL (Package-By-Layer) へ寄せすぎない 〜Controllerだけのディレクトリ 〜Repositoryだけのディレクトリ 何が嬉しいのか @psalm-internal がうまく機能するよう書く
  30. 13. みんな(会社を動かして)PHP Foundation に寄付をするんだ
  31. おしまい
Advertisement