Slide 1

Slide 1 text

Rector ではじめる "運用を止めない" PHP アップグレード 株式会社コロプラ 技術基盤本部 サーバー基盤チーム 工藤 剛 1 #phperkaigi #a #colopltech

Slide 2

Slide 2 text

アジェンダ 2 1. 自己紹介 2. Rector ってなに? 3. Rector のすごいところ 4. 白猫プロジェクト NEW WORLD'S による実例 5. テスト及びデプロイ 6. まとめ #phperkaigi #a #colopltech

Slide 3

Slide 3 text

3 2017 年に新卒入社 各種タイトルの運用に携わった後、 SRE チームに Join ミドルウェアのバージョンアップや PHP 周りを主に担当 php-src ext-random の (一応) メンテナ Twitter: @zeriyoshi Mastodon: @[email protected] 氏名  : 部署名 : 工藤 剛 技術基盤本部 第2バックエンドエンジニア部 サーバー基盤グループ SREチーム #phperkaigi #a #colopltech 自己紹介

Slide 4

Slide 4 text

4 Rector ってなに? #phperkaigi #a #colopltech

Slide 5

Slide 5 text

5 PHP-Parser や PHPStan を用い、 "静的解析" 結果を使うリファクタリングツール https://github.com/rector/rector Rector = (超強力) リファクタリングツール $ composer require –dev rector/rector #phperkaigi #a #colopltech

Slide 6

Slide 6 text

6 Rector のすごいところ #phperkaigi #a #colopltech

Slide 7

Slide 7 text

7 左 (PHP 8.0) のコードに右の Rector ルールを適用すると... #phperkaigi #a #colopltech

Slide 8

Slide 8 text

8 8.2 相当の機能を利用するよう自動的にリファクタ #phperkaigi #a #colopltech

Slide 9

Slide 9 text

9 PHPStan を用いた静的解析 + PHP-Parser ベースの AST 操作 = PHPDoc の解釈や型推論までできる 超強力リファクタリングツール つまり #phperkaigi #a #colopltech

Slide 10

Slide 10 text

10 ほかにも... #phperkaigi #a #colopltech

Slide 11

Slide 11 text

11 ダウングレードもできる! $ composer require –dev rector/rector-downgrade-php rector/rector-downgrade-php https://github.com/rectorphp/rector-downgrade-php ちなみに Rector 自体も Rector を使って PHP 7.2 以降であれば動くコードに変換して リリースされている (!)

Slide 12

Slide 12 text

12 アップグレード戦略 #phperkaigi #a #colopltech

Slide 13

Slide 13 text

アップグレード戦略 13 ● 積極的なコードリファクタリングはしない ○ PHP 7.4, 8.1 両方で同様に動作するコードを書く ■ 曖昧比較の非互換 => colopl_bc (内製 PHP Extension) で吸収 ● 曖昧比較を ext-colopl_bc の関数に Rector ですべて変換 ● CI を用いて非互換が生じるコードが紛れ込んでいないか常に検査 ○ Rector を実行し、差分が出ないかを常に検査 ○ PHPStan のルールを書いて非互換コードが生じないよう常に検査 ○ ダメ押しに PHPCompatibility による検査 ● 外部依存関係は 7.4 / 8.1 を両立できるところまで可能な限り更新 ○ Symfony コンポーネント郡 ○ PHPUnit 3 + 独自 patch -> PHPUnit 9 #phperkaigi #a #colopltech

Slide 14

Slide 14 text

● switch 文における曖昧比較演算子にするルール ○ switch ($foo) { case 'bar': } -> switch (true) { case $foo == 'bar': } ● 曖昧比較演算子を互換関数にするルール ○ 1 == 2; -> \Colopl\BackwardsCompatibility\Php74\eq(1, 2); ■ switch 文の == も最終的にこれで変換される ● APC から APCu へ移行するためのルール ○ apc_clear_cache('user'); -> apcu_clear_cache(); 等 ● 曖昧比較演算を伴う配列関連の関数を互換関数にするルール ○ in_array, array_search, array_keys -> ext-colopl_bc の関数に 置換 書いた主な Rector ルール 14 #phperkaigi #a #colopltech

Slide 15

Slide 15 text

書いた主な Rector ルール 15 ● オブジェクトへの array_key_exists を property_exists にするルール ○ array_key_exists('key', $stdClass); -> property_exists($stdClass, 'key'); ● array_multisort の曖昧比較・ソート順変更を互換関数にするルール ○ array_multisort -> \Colopl\BackwardsCompatibility\Php74\array_multisort ● 以前のソートの挙動を再現した互換関数にするルール ○ sort -> \Colopl\BackwardsCompatibility\Php74\sort #phperkaigi #a #colopltech

Slide 16

Slide 16 text

16 PHP 7.4 / 8.1 両対応な コードベースを常に維持できるため 移行期間中開発側で意識する必要がない 並行で新規開発中のコードも 自動的に 7.4 / 8.1 両対応になる これらのルールを常に適用し続ければ... #phperkaigi #a #colopltech

Slide 17

Slide 17 text

17 テスト及び デプロイ #phperkaigi #a #colopltech

Slide 18

Slide 18 text

並行 QA + インスタンス入れ替え 18 ● PHP 7.4 , 8.1 環境それぞれで同一のテストを一通り実施 ○ ユニットテスト ○ 実機デバッグ ○ 並行開発している新規機能の QA ● ロードバランサーに対し、新旧インスタンスを同時に投入 ○ 徐々に新インスタンスの比率を上げていき、最終的に旧インスタンスを すべて LB から外す ■ 旧インスタンス: Apache2 + mod_php + PHP 7.4 ■ 新インスタンス: nginx + php-fpm + PHP 8.1 ○ コードベースが完全に同一なため、デプロイミスは発生しない ● 正常に動作していることを確認し、旧インスタンスを削除 #phperkaigi #a #colopltech

Slide 19

Slide 19 text

残作業 19 ● 各開発サーバーを作り直し ○ 長期運用タイトルのため、 Unity の AssetBundle などのリソースが巨大 ■ 新規構築したサーバーへの展開に 4 時間くらいかかる ● 開発チームと連携しつつ、徐々に旧環境を削除していく ○ コードベースが同じなので PHP 8.1 更新後のコードを取り込んでも盛大 に conflict したりはしない ■ 新規開発の効率を維持できた ● Rector によるコード変換を CI から外し、 PHP 8.1 の新機能を 使える状態へ => ハッピーな世界 #phperkaigi #a #colopltech

Slide 20

Slide 20 text

20 まとめ #phperkaigi #a #colopltech

Slide 21

Slide 21 text

まとめ 21 ● 常に PHP 7.4 / 8.1 で動作するコードベースを維持できた! ○ 新規開発にマイグレーション対応が追いつかない、というあるあるを自 動化で回避できた ● ルールを書くまでの学習コストは少々高め ○ 割と単純なルールなら書けるので、命名規則等をしっかりとやっていれ ばラフなルールを書くことは可能 ■ とはいえ PHPStan による型推論情報も利用できるので活用してい くとより良い ● 組み込みのルールがめちゃくちゃ充実している ○ 今回はコード差分を最小限にするために独自ルールしか 使わなかったが、移行に使える組み込みルールも豊富にある ○ Laravel マイグレーション用のルールとかもある https://github.com/driftingly/rector-laravel #phperkaigi #a #colopltech

Slide 22

Slide 22 text

22 ご意見・ご感想などなんでも お待ちしております!!! Twitter: @zeriyoshi #phperkaigi #a #colopltech