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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  13. アップグレード戦略
    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

    View Slide

  14. ● 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

    View Slide

  15. 書いた主な 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  20. 20
    まとめ
    #phperkaigi #a #colopltech

    View Slide

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

    View Slide

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

    View Slide