Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
レガシーシステムへのPHPStan導入から半年での効果と課題
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
don
February 11, 2024
Technology
2.4k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
レガシーシステムへのPHPStan導入から半年での効果と課題
don
February 11, 2024
More Decks by don
See All by don
レガシーシステムへのPHPStan導入から半年での課題と効果
bosshawk
1
2.2k
息の長いサービスの PHP8バージョンアップで見えた 課題と解決法 / Problems and solutions found when upgrading long-term services to PHP8
bosshawk
0
2.9k
レガシーシステムにおけるPHP8バージョンアップのアプリ対応記録
bosshawk
0
2.3k
[おすすめの技術書 LT会 - vol.2] 体系的に学ぶ安全なWebアプリケーションの作り方
bosshawk
0
21k
[PHPerKaigi 2021 (LT)] 新社会人のコード品質カイゼン記録
bosshawk
1
1.5k
Other Decks in Technology
See All in Technology
10倍の生産性を実現するAI駆動並列エージェントのすべて
kumaiu
5
1.4k
あなたの AI ワークスペースに、 専門コーダーを連れてくる - Amazon Quick Desktop 最新情報
kawaji_scratch
1
130
【Cyber-sec+】経営層を"動かす"ための考え方
hssh2_bin
0
140
AI駆動開発を通して感じた、 AI時代のデザイナーの役割変化
whisaiyo
2
1.7k
NAB Show 2026 動画技術関連レポート / NAB Show 2026 Report
cyberagentdevelopers
PRO
0
170
2026TECHFRESH畢業分享會 - Lightning Talk - 打造精準高效的 MCP 設計模式與測試實務
line_developers_tw
PRO
0
890
Disciplined Vibes: Scaling AI-Assisted Engineering
sheharyar
0
140
200個のGitHubリポジトリを横断調査したかった
icck
0
120
RSA暗号を手計算したくなること、ありますよね?? (20260615_orestudy6_rsa)
thousanda
0
300
社内 AI エージェント Synapse と セマンティックレイヤーの育て方
hiroakis
2
1.8k
AWSシリコン最前線 〜AI時代のチップ選択を読み解く〜
htokoyo
2
520
Oracle AI Database@Google Cloud:サービス概要のご紹介
oracle4engineer
PRO
6
1.5k
Featured
See All Featured
Leo the Paperboy
mayatellez
7
1.8k
Scaling GitHub
holman
464
140k
The Curious Case for Waylosing
cassininazir
1
380
RailsConf 2023
tenderlove
30
1.5k
A Tale of Four Properties
chriscoyier
163
24k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
610
Designing for humans not robots
tammielis
254
26k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
310
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
122
22k
Believing is Seeing
oripsolob
1
140
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
250
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
Transcript
#phpkansai #b レガシーシステムへの PHPStan 導入から 半年での課題と効果 2023 年02 月11 日
PHP カンファレンス関西2023 don (頓花) ©RAKUS Co., Ltd.
don (頓花) 出身:大阪府岸和田市 年齢:29 歳 趣味:ゲーム, アニメ, マンガ, デバイス収集 etc...
略歴 2019 年 株式会社ラクス入社 技術スタック PHP 歴: 5 年 登壇経験 2 回 ( オフラインは初登壇) #phpkansai #b 自己紹介 ©RAKUS Co., Ltd. 2
楽楽販売 クラウド型の販売管理システム Web アプリケーション バックエンドはPHP /PostgreSQL 独自フレームワーク PHP5 の時代から 15
年以上 続くソースコード 約35 万行(PHP コードのみで) #phpkansai #b プロダクトの説明 ©RAKUS Co., Ltd. 3
なぜ導入したか PHPStan の導入 導入後の効果と課題 まとめ #phpkansai #b アジェンダ ©RAKUS Co.,
Ltd. 4
ところで、みなさん #phpkansai #b ©RAKUS Co., Ltd. 5
静的解析ツールは何を使っていますか? #phpkansai #b ©RAKUS Co., Ltd. 6
導入していた静的解析ツール PhpStorm のInspection ローカルで実行する SonarQube 重複コードのチェックなど 自動で実行する SonarQube とは 多くのプログラミング言語をサポートしている静的解析ツール
※ https://docs.sonarsource.com/sonarqube/latest/ #phpkansai #b 静的解析ツール ©RAKUS Co., Ltd. 7
しかし、 それらの静的解析ツールでは こんな課題が発生していました... 。 #phpkansai #b ©RAKUS Co., Ltd. 8
PhpStorm のInspection の課題 新しい指摘と既存の指摘の判別がつかない 自動で実行する仕組みがない ⇒ 解析は強力であるが、修正可否をチェックしづらい SonarQube の課題 型のチェックなどの解析がない
カスタムルールの追加が難しい ⇒ 言語に特化した静的解析が実施しづらい #phpkansai #b 既存の静的解析ツールでの課題 ©RAKUS Co., Ltd. 9
また、 静的解析ツール以外の課題も... #phpkansai #b ©RAKUS Co., Ltd. 10
null に関連する不具合が頻発 null オブジェクトへの参照エラー 関数の nullable でない型の引数に null を渡す コードレビューの時間増加による開発効率の低下
新任メンバー増加 #phpkansai #b 開発チームの課題 ©RAKUS Co., Ltd. 11
少し本筋から外れますが #phpkansai #b ©RAKUS Co., Ltd. 12
PHP の最近の動向について #phpkansai #b ©RAKUS Co., Ltd. 13
新機能 型付きプロパティの導入 列挙型/交差型/never 型/true ・false ・null 型の追加 readonly アクセス修飾子/readonly クラスの導入
非推奨 PHP 8.0 :非厳密な比較演算子の挙動変更 PHP 8.1 :ビルトイン関数の nullable でない引数に null を渡す PHP 8.2 :動的プロパティが非推奨 #phpkansai #b 型定義の厳密化するPHP ©RAKUS Co., Ltd. 14
静的型付け言語に近づいていくPHP #phpkansai #b ©RAKUS Co., Ltd. 15
閑 話 / 休 題 Kan Wa Kyu Dai
課題 null に関連する不具合が頻発 コードレビューの時間増加による開発効率の低下 PhpStorm のInspection は自動化されていない SonarQube はPHP のコード解析力が足りない
⇒ 既存の静的解析ツールでは力不足... 開発チームの課題
他に良い解析ツールはないか... ?
None
PHPStan PHP コードを静的に解析する 実行時にエラーとなるような問題のあるコードを検知する https://phpstan.org/ PHPStan のメリット 型定義のチェック 独自ルールの追加の容易さ #phpkansai
#b PHPStan とは ©RAKUS Co., Ltd. 20
なぜ導入したか PHPStan の導入 導入後の効果と課題 まとめ #phpkansai #b アジェンダ ©RAKUS Co.,
Ltd. 21
PHPStan を導入する上では 解析レベルをどうするか 既存エラーへの対処 どこで実行するか #phpkansai #b PHPStan 導入 ©RAKUS
Co., Ltd. 22
#phpkansai #b PHPStan 導入:解析レベル Level 概要 0 基本的なチェック、未知のクラス、未知の関数、 $this 上で呼び出された未知のメソッド、それらのメソッドや関数に渡された引数の
数が間違っている、常に未定義の変数をチェック 1 未定義の変数、 __call と __get を持つクラスの未知のマジックメソッドとプロパティがある可能性がある 2 ( $this だけでなく) すべての式で未知のメソッドをチェックし、PHPDocs を検証する 3 戻り値の型、プロパティに割り当てられた型の確認 4 基本的なデッドコードチェック( instanceof やその他の型チェックが常に false / 到達しない else 文/ return 後の到達不能コード) 5 メソッドや関数に渡される引数の型チェック 6 タイプヒントの欠落を報告する 7 部分的に間違っている論理和型の報告。論理和型の一部の型にしか存在しないメソッドを呼び出した場合、レベル7 はそのことを報告し 始めます( その他の不正確な状況も) 8 nullable 型に対するメソッド呼び出しとプロパティへのアクセスを報告する 9|max 混合型に厳密であること。この型で唯一許される操作は、この型を別の混合型に渡すことである ©RAKUS Co., Ltd. 23
検討 既存のレガシーコードに高い解析レベルが修正コストが高い 直近でもnull に関連する不具合が頻発していたこともありnull チェックはしたい 対応 解析レベルは8 既存コードは検知対象外とする Baseline を作成して対応
#phpkansai #b PHPStan 導入:解析レベルと既存コード ©RAKUS Co., Ltd. 24
既存の解析ツールの課題 PhpStorm のInspection はローカル実行のみ SonarQube の実行も手動でブランチを指定が必要 対応 PR 単位で自動チェックされるようにCI を設定
#phpkansai #b PHPStan 導入:自動化 ©RAKUS Co., Ltd. 25
ところで、気になりませんか? #phpkansai #b ©RAKUS Co., Ltd. 26
レガシーコードに対して 解析レベルをほぼMAX( レベル8) で 実行するとどれぐらいエラーが出るのか #phpkansai #b ©RAKUS Co., Ltd.
27
解析レベル8 で解析実行だ! #phpkansai #b ©RAKUS Co., Ltd. 28
約60000 件のエラーを検知!! #phpkansai #b ※対象 約5000 ファイル(約35 万行) ©RAKUS Co.,
Ltd. 29
ですよね... #phpkansai #b ©RAKUS Co., Ltd. 30
解析レベルはレベル8 既存コードはベースラインを設定し指摘対象外へ PR 単位で自動でチェックされるようにCI を設定 #phpkansai #b PHPStan 導入 ©RAKUS
Co., Ltd. 31
なぜ導入したか PHPStan の導入 導入後の効果と課題 まとめ #phpkansai #b アジェンダ ©RAKUS Co.,
Ltd. 32
効果 PHPStan でバグを発見 カスタムルールを追加 コードレビュー対応時間の軽減 etc... #phpkansai #b 効果①:具体的な効果 ©RAKUS
Co., Ltd. 33
例)PHPStan でバグを発見 関数のオーバーライドの引数の型の不具合の発見 HogeMenuController.php:18:Method HogeMenuController::viewAction() overrides method AbstractMenuController::viewAction() but misses
parameter #1 $form. 大規模な構成見直しを実施していたこともあり、修正量が多くコードレビューか ら漏れていた。 PHPStan を導入していなければ、そのままリリースされていた可能性も... #phpkansai #b 効果①:具体的な効果 ©RAKUS Co., Ltd. 34
効果 メンバーのセルフチェックの品質向上 各メンバーの型への意識が向上 #phpkansai #b 効果②:メンバーの意識向上 ©RAKUS Co., Ltd. 35
課題 指摘の意味を調べるのに時間がかかる 1PR のコード量が多く、指摘が多くなる 対応 メンバーが指摘なれることで解決 PR の粒度を小さくする #phpkansai #b
課題と対応①:指摘の修正に時間がかかる ©RAKUS Co., Ltd. 36
例) $ ./vendor/bin/phpstan analyse --no-progress --memory-limit=2G --error-format=raw $(cat $CI_PROJECT_DIR/target.txt) Note:
Using configuration file ./phpstan.neon. ... HogeCommand.php:25:Property HogeCommand::$requestParameter has no type specified. HogeCommand.php:704:Method HogeCommand::mailSend() has no return type specified. HogeCommand:704:Method HogeCommand::mailSend() has parameter $condition with no type specified. HogeCommand:704:Method AHogeCommand::mailSend() has parameter $aIsError with no type specified. HogeCommand:749:Offset 'user_name' might not exist on array|null. FileInfo.php:23:Class FileInfo has an uninitialized readonly property $fileId. Assign it in the constructor. FileInfo.php:24:Class FileInfo has an uninitialized readonly property $fileName. Assign it in the constructor. FileInfo.php:25:Class FileInfo has an uninitialized readonly property $filePath. Assign it in the constructor. FileInfo.php:25:Property FileInfo::$filePath is never read, only written. FileInfo.php:26:Class FileInfo has an uninitialized readonly property $fileOrder. Assign it in the constructor. FileInfo.php:26:Property FileInfo::$fileOrder is never read, only written. FileInfo.php:27:Class FileInfo has an uninitialized readonly property $fileType. Assign it in the constructor. ... #phpkansai #b 課題と対応①:指摘の修正に時間がかかる ©RAKUS Co., Ltd. 37
課題 array を引数とする場合に正確な型指定が必要 match 文のdefaut 指定 標準関数が複数の型を返す問題 etc... 対応 除外ルールを設定
#phpkansai #b 課題と対応②:過剰な指摘が多数発生 ©RAKUS Co., Ltd. 38
例)array を引数とする場合に正確な型指定 DB へのアクセスした値を配列で持ち回っているために指摘される 指摘に対応すると返値の配列を型も含めてすべて指定する必要がある → 除外ルールへ設定 既存処理の呼び出しで問題になるためすべて対応することは難しいと判断 /** *
@return array{"foo": int, "bar": string} */ function fetchHoge(int $id): array { return $this->pdo->query("SELECT foo,bar FROM hoge WHERE id = $id")->fetch(); } #phpkansai #b 課題と対応②:過剰な指摘が多数発生 ©RAKUS Co., Ltd. 39
課題 型定義がない PHPDoc の型定義が間違っている 対応 ボーイスカウトルールを設定 型定義を追加 PHPDoc で型を型定義 ※
基本は動作に影響のないようにPHPDoc の追加 #phpkansai #b 課題と対応③:既存コードの型定義不足 ©RAKUS Co., Ltd. 40
順調に課題を解消していくが、 ここで問題発生... #phpkansai #b ©RAKUS Co., Ltd. 41
メイン担当者が不在へ... ( メンバーの異動などが重なり...) #phpkansai #b ©RAKUS Co., Ltd. 42
課題 どの粒度で修正するのかがチーム全体で決まらない ルールが決まり切らずに対応がバラバラへ... 暫定対応 どこまで修正するかはレビュアーとの認識合わせで合意 というルール #phpkansai #b 課題と対応④:メイン担当者が不在による課題 ©RAKUS
Co., Ltd. 43
残課題 ローカル実行する手段が少ないため再チェックに時間が掛かる 対応案 ローカルで簡易に実行できる手段の確立 CI の実行時間問題の解消 #phpkansai #b 今後 ©RAKUS
Co., Ltd. 44
なぜ導入したか PHPStan の導入 導入後の効果と課題 まとめ #phpkansai #b アジェンダ ©RAKUS Co.,
Ltd. 45
得られたこと 型への意識が向上しクリーンなコードが作られるようになった レガシーなコードであってもベースラインや除外ルールを設定することで、解析 レベルが高い状態で運用することができた 注意点 自動でチェックされる仕組みにすること メイン担当者を決めてルールを整備すること #phpkansai #b まとめ
©RAKUS Co., Ltd. 46
ご清聴ありがとうございました。 #phpkansai #b ©RAKUS Co., Ltd. 47