Page 1
実践PHPStan
Practical PHPStan
pixiv Inc.
USAMI Kenta
PHP Conference Okinawa 2022
2022-08-27
公開日:
by USAMI Kenta@tadsan
に沖縄県那覇市のZORKS沖縄 および YouTube Liveで開催された『PHPカンファレンス沖縄2022』でレギュラートーク(30分)として発表しました。
PHP Conference Okinawa 2022
2022-08-27
お前誰よ
tadsanのあれこれが読める場所
今回のゴール
今回やらないこと
PHPStanの詳細な設定
CI環境の組み方ジェネリクス/条件型
このスライドは本日中に公開されます
この発表では知っておくべき機能を雑に取り上げるので本番運用/提案の前にドキュメントを自身でしっかり読み込みましょう。
それでもわからないことがあればTwitterかSlackのphpusers-ja#type-safeで尋ねてください
PHPStan使ってますか?
リンター
あなたとPHPStanいますぐダウンロード
PHP 7.2以上ならプロジェクトに追加しよう
プロジェクトに追加できないなら
PHPStanを入れてどうするの
解析能力に関しては専門のツールの方が強い
解析結果はリアルタイム表示しよう
arrayとarray<mixed>とmixed[] を混同しない
@param とか @returnを執拗に全部埋めてくる
arrayとarray<mixed>とmixed[] を混同しない
⛱
AまたはB(複雑な式は書けない)
AおよびB(複雑な式は書けない)
intまたはAまたは「BおよびC」またはnull(一定の制約下で複雑な型も書ける)
Aまたはnullデフォルトで許容しない
任意の(すべての)型を表す型(ほかの言語でのany)
型宣言 vs PHPDoc(型注釈)
動的言語における現実的な型の付け方になります
無駄なPHPDocは書かない
arrayとarray<mixed>とmixed[] を混同しない
@param とか @returnを執拗に全部埋めてくる
arrayとarray<mixed>とmixed[] を混同しない
型宣言があればPHPDocなくても足りるんじゃないの?
PHPStanにはもっと強力な型がある
PHPStanを使ってみよう
オンラインサンドボックス
いますぐダウンロード
いますぐダウンロードしなくてもいい
こういう関数を考えてみましょう
本を検索する関数検索ワード
本を検索する関数検索ワード何これ
本を検索する関数検索ワード何これ
何これ
$options配列の中身わからん
$options配列の中身わからん
returnされる配列の中身わからん
配列の中身にはあらゆる可能性
型がついていないとはどういうことか
渡す型が十分に絞り込まれていないと容赦なく叱ってくれる
必要のないところにmixedは書かない
型宣言があれば足りるんじゃないの?
型宣言だけでは表現力が不足している
[['id' => 123, 'name' => '野比のび太'],['id' => 234, 'name' => '源静香'],]
list<int>
[['id' => 123, 'name' => '野比のび太'],['id' => 234, 'name' => '源静香'],]
list<int>
array<int,string>
[['id' => 123, 'name' => '野比のび太'],['id' => 234, 'name' => '源静香'],]
list<int>
array<int,string>
array{id:int, name:string}
[['id' => 123, 'name' => '野比のび太'],['id' => 234, 'name' => '源静香'],]
list<int>
array<int,string>
array{id:int, name:string}
[['id' => 123, 'name' => '野比のび太'],['id' => 234, 'name' => '源静香'],]
list<array{id:int, name:string}>
fullかpartialなのにperfect
fullかpartialなのにperfect
ほんとはtitleなのにnameでアクセス
PHPStanの強力な型
型名について
頭と単語区切りを大文字にする)が一般的だが、bookのように小文字も定義可
@phpstan-param @phpstan-return @phpstan-var にする
整数範囲型
リテラル型・定数型
key-of型・value-of型
(Map/ハッシュテーブル)の区別がない
配列の中身がキーごとに別のデータが格納されるときは array{...}
array-shapes (Object-like arrays)
array<Type>
list<Type>
non-empty-*型
検索モードのリストvalue-of<定数>
検索モードのリストvalue-of<定数>
価格は正の整数
検索モードのリストvalue-of<定数>
空文字列を検索禁止する
価格は正の整数
(警告)空文字列を検索
(警告)空文字列を検索
(警告)price == 0 はありえない
ばっちり型がつきましたね
基本的な型の付け方
array{} とか覚えなくてよくない?
DTO (Data Transfer Object)
責務が小さく解析もしやすくなるが今回の本題ではないので割愛
検索モードオプションは配列ではなくクラス
著者
書籍
著者
書籍
コンストラクタプロモーション
オプション型宣言戻り値PHPDoc
が静的解析もしやすく、実行時に意図しない値も紛れにくい
一気に下がり、名前付き引数によってコード上に意図も込めやすくなった
いくつも作ることになるとしんどくなってくる
かくしてPHPに完璧な型がつきました
これで済むならPHPは型なしとか呼ばれてない
型なしはどこから来るの?
型なしの値
😇
関数に渡す
もちろんPhpStorm上で表示できる
falseだったら関数を抜けることで
falseが混じる可能性を排除falseだったら関数を抜けることで
falseが混じる可能性を排除
falseではないと表明
分岐ごとに範囲が分かれ合流すると戻る
変数すべてmixed
型が不定のメソッド呼び出し
ただし単なるコメントなので実態に反する型も付けられてしまうので要注意
実装側の責任とする/型宣言による自動型チェックで保証されるので @var
期待通りの構造の配列/クラスにマッピングする
場合は、 assert($var instaceof Foo) のようにチェックしておくことでエラーメッセージがわかりやすくなる
標準関数 vs 型
PHPStanはオンラインで型チェックできる
PHPStanは完璧じゃない
期待した型がつかないと思ったら最小のコードをオンラインでチェックしましょう
バグの場合もあるし実装してPRを送るチャンスかもしれない
現在のPHPStanの仕様上このような型はつけられない
そのうち(誰かが実装完了すれば)改善する見込みはある
PHPStanの実装は超簡単だとは言えないが仕事でPHPやってたら手を出せないほど難解というほどではない
みなさんもチャレンジしてみましょう
PHPStanで楽しい型付けライフを
