Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rector ではじめる "運用を止めない" PHP アップグレード

Rector ではじめる "運用を止めない" PHP アップグレード

※資料内の参照リンクを選択し閲覧する場合は、ダウンロードをお願いいたします

\積極的に技術発信を行なっております/

▽ Twitter/COLOPL_Tech
https://twitter.com/colopl_tech

▽ connpassページ
http://colopl.connpass.com

▽ COLOPL Tech Blog
http://blog.colopl.dev

COLOPL Inc.

March 28, 2023
Tweet

More Decks by COLOPL Inc.

Other Decks in Technology

Transcript

  1. アジェンダ 2 1. 自己紹介 2. Rector ってなに? 3. Rector のすごいところ

    4. 白猫プロジェクト NEW WORLD'S による実例 5. テスト及びデプロイ 6. まとめ #phperkaigi #a #colopltech
  2. 3 2017 年に新卒入社 各種タイトルの運用に携わった後、 SRE チームに Join ミドルウェアのバージョンアップや PHP 周りを主に担当

    php-src ext-random の (一応) メンテナ Twitter: @zeriyoshi Mastodon: @[email protected] 氏名  : 部署名 : 工藤 剛 技術基盤本部 第2バックエンドエンジニア部 サーバー基盤グループ SREチーム #phperkaigi #a #colopltech 自己紹介
  3. 5 PHP-Parser や PHPStan を用い、 "静的解析" 結果を使うリファクタリングツール https://github.com/rector/rector Rector =

    (超強力) リファクタリングツール $ composer require –dev rector/rector #phperkaigi #a #colopltech
  4. 9 PHPStan を用いた静的解析 + PHP-Parser ベースの AST 操作 = PHPDoc

    の解釈や型推論までできる 超強力リファクタリングツール つまり #phperkaigi #a #colopltech
  5. 11 ダウングレードもできる! $ composer require –dev rector/rector-downgrade-php rector/rector-downgrade-php https://github.com/rectorphp/rector-downgrade-php ちなみに

    Rector 自体も Rector を使って PHP 7.2 以降であれば動くコードに変換して リリースされている (!)
  6. アップグレード戦略 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
  7. • 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
  8. 書いた主な 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
  9. 並行 QA + インスタンス入れ替え 18 • PHP 7.4 , 8.1

    環境それぞれで同一のテストを一通り実施 ◦ ユニットテスト ◦ 実機デバッグ ◦ 並行開発している新規機能の QA • ロードバランサーに対し、新旧インスタンスを同時に投入 ◦ 徐々に新インスタンスの比率を上げていき、最終的に旧インスタンスを すべて LB から外す ▪ 旧インスタンス: Apache2 + mod_php + PHP 7.4 ▪ 新インスタンス: nginx + php-fpm + PHP 8.1 ◦ コードベースが完全に同一なため、デプロイミスは発生しない • 正常に動作していることを確認し、旧インスタンスを削除 #phperkaigi #a #colopltech
  10. 残作業 19 • 各開発サーバーを作り直し ◦ 長期運用タイトルのため、 Unity の AssetBundle などのリソースが巨大

    ▪ 新規構築したサーバーへの展開に 4 時間くらいかかる • 開発チームと連携しつつ、徐々に旧環境を削除していく ◦ コードベースが同じなので PHP 8.1 更新後のコードを取り込んでも盛大 に conflict したりはしない ▪ 新規開発の効率を維持できた • Rector によるコード変換を CI から外し、 PHP 8.1 の新機能を 使える状態へ => ハッピーな世界 #phperkaigi #a #colopltech
  11. まとめ 21 • 常に PHP 7.4 / 8.1 で動作するコードベースを維持できた! ◦

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