Slide 1

Slide 1 text

半年かけてPHP5.6 からPHP7.4まで バージョンアップした 苦労と工夫 PHPカンファレンス福岡2024

Slide 2

Slide 2 text

自己紹介 山内 啓輔/けちーん Cake.jpというスイーツのECサイトを運営する会社でエンジニアをしています 主にPHPを書いてます/PHP歴は3年くらい 北海道出身/福岡在住 こんな髪型ですが2児(小5男子と小4男子)のパパです

Slide 3

Slide 3 text

今日の内容 バージョンアップの歴史 1. 苦労しながら倒したヤツら 2. 工数を減らすための工夫 3. まとめ 4.

Slide 4

Slide 4 text

バージョンアップの歴史 1. 苦労しながら倒したヤツら 2. 工数を減らすための工夫 3. まとめ 4.

Slide 5

Slide 5 text

バージョンアップ部隊(基盤チーム) 担当:2名(エンジニア総数は6名) 工数:1日/週 バージョンアップ以外にもやることがあったりもする

Slide 6

Slide 6 text

バージョンアップの歴史 プロジェクト始動:2023/04 まずは大量に出ているWarningやNoticeを(ある程度)倒す →Sentry を導入したい 過去に軽い気持ちで導入したら、とあるcsvの処理でNoticeが 出過ぎてタイムアウトしたことがある。。。 ※Sentryはエラーの監視とトラッキングを行うツール ※

Slide 7

Slide 7 text

テスト環境の整備 前提 バージョンアップ対象リポジトリ ECサイト 管理画面 共通処理

Slide 8

Slide 8 text

テスト環境の整備 前提 バージョンアップ対象リポジトリ ECサイト 管理画面 共通処理 この2つが同じテスト環境で動いている

Slide 9

Slide 9 text

テスト環境の整備 テスト環境はコンテナ化されていなかったので、複数バージョ ン存在することができなかったのでDockerを導入 2023/08末に完了

Slide 10

Slide 10 text

Dockerの導入

Slide 11

Slide 11 text

2023/08末 バージョンアップ開始!

Slide 12

Slide 12 text

まずは5.6から7.0 最初は1つのリポジトリを、2人で分担して進めていた

Slide 13

Slide 13 text

ECサイトが7.0に 初めてのバージョンアップに成功!偉業達成!!※ ※当社比 2023/09上旬 ECサイトが7.0になる

Slide 14

Slide 14 text

管理画面も7.0に 立て続けにバージョンアップに成功!偉業達成!!※ ※当社比 2023/09下旬 管理画面が7.0になる

Slide 15

Slide 15 text

そして時は流れ・・・ (あまり時間がないので、以下略の意)

Slide 16

Slide 16 text

2024/06 8.0へのバージョンアップに成功!

Slide 17

Slide 17 text

バージョン EC 管理画面 開始 2023/08 2023/09 7.0 2023/09 2023/09 7.1 2023/11 2023/10 7.2 2023/12 2024/01 7.3 2024/02 2024/01 7.4 2024/03 2024/03 8.0 2024/06 2024/06

Slide 18

Slide 18 text

0.1ずつ刻んでいった理由 比較的短いリリースサイクルで進めたかった

Slide 19

Slide 19 text

理由その1 過去にバージョンアップをしようとしたけど、自然消滅してし まったことがあるので、プロジェクトが継続するかわからなか った 比較的短いリリースサイクルで進めたかった

Slide 20

Slide 20 text

理由その2 使える工数は多くないので、リリースサイクルが長いとモチベ ーションがもたない可能性があった 比較的短いリリースサイクルで進めたかった

Slide 21

Slide 21 text

バージョンアップの歴史 1. 苦労しながら倒したヤツら 2. 工数を減らすための工夫 3. まとめ 4.

Slide 22

Slide 22 text

5.6 → 7.0

Slide 23

Slide 23 text

5.6 → 7.0 対応一覧 ・Notice: Undefined offset ・Notice: Undefined index ・Notice: Undefined variable ・Warning: Missing argument ・set_magic_quotes_runtimeの廃止

Slide 24

Slide 24 text

Notice: Undefined index[offset]

Slide 25

Slide 25 text

7.0 → 7.1

Slide 26

Slide 26 text

7.0 → 7.1 対応一覧 Deprecated: Non-static method Hoge::fuga() should not be called statically Fatal error: Too few arguments to function This test did not perform any assertions rand() と srand() が、それぞれ mt_rand() と mt_srand() のエイ リアスとなる

Slide 27

Slide 27 text

Deprecated: Non-static method Hoge::fuga() should not be called statically

Slide 28

Slide 28 text

This test did not perform any assertions

Slide 29

Slide 29 text

7.1 → 7.2

Slide 30

Slide 30 text

7.1 → 7.2 対応一覧 Warning: count(): Parameter must be an array or an object that implements Countable Fatal error: must be compatible with PHPUnit\Framework\TestCase::setUp(): void

Slide 31

Slide 31 text

Warning: count(): Parameter must be an array or an object that implements Countable

Slide 32

Slide 32 text

Fatal error: must be compatible with PHPUnit\Framework\TestCase::setUp(): void

Slide 33

Slide 33 text

7.2 → 7.3

Slide 34

Slide 34 text

7.2 → 7.3 対応一覧 Deprecate assertRegExp() Deprecate assertArraySubset() preg_match(): Compilation failed: range out of order in character class

Slide 35

Slide 35 text

preg_match(): Compilation failed: range out of order in character class

Slide 36

Slide 36 text

7.3 → 7.4

Slide 37

Slide 37 text

7.3 → 7.4 対応一覧 Notice: Trying to access array offset on value of type null[bool] Notice: Trying to get property of non-object runkit削除 qdmail対応

Slide 38

Slide 38 text

No tice: Trying to access array offset on value of type null[bool]

Slide 39

Slide 39 text

No tice: Trying to access array offset on value of type null[bool]

Slide 40

Slide 40 text

No tice: Trying to access array offset on value of type null[bool]

Slide 41

Slide 41 text

qdmail対応

Slide 42

Slide 42 text

qdmail対応

Slide 43

Slide 43 text

qdmail対応

Slide 44

Slide 44 text

qdmail対応

Slide 45

Slide 45 text

7.4 → 8.0

Slide 46

Slide 46 text

7.4 → 8.0 対応一覧 Warning: Trying to access array offset on value of type null[bool] Fatal error: Uncaught Error: Non-static method A::aa() cannot be called statically Fatal error: Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array, null given Fatal error: Uncaught ValueError: Unknown format specifier "v" Fatal error: Array and string offset access syntax with curly braces is no longer supported 古いコンストラクタ対応 lcobucci/jwt対応 amazon-pay対応

Slide 47

Slide 47 text

古いコンストラクタ対応

Slide 48

Slide 48 text

古いコンストラクタ対応

Slide 49

Slide 49 text

古いコンストラクタ対応

Slide 50

Slide 50 text

amazon-pay対応

Slide 51

Slide 51 text

amazon-pay対応 OLD amzn/amazon-pay-sdk-php NEW amzn/amazon-pay-api-sdk-php

Slide 52

Slide 52 text

amazon-pay対応 OLD amzn/amazon-pay-sdk-php NEW amzn/amazon-pay-api-sdk-php ← こっちで起きる

Slide 53

Slide 53 text

amazon-pay対応 OLD amzn/amazon-pay-sdk-php NEW amzn/amazon-pay-api-sdk-php ← こっちで起きる Fatal error: Declaration of AmazonPay\Client::setLogger(?Psr\Log\LoggerInterface $logger = null) must be compatible with Psr\Log\LoggerAwareInterface::setLogger(Psr\Log\LoggerInterface $logger): void

Slide 54

Slide 54 text

amazon-pay対応 amzn/amazon-pay-sdk-php psr/log

Slide 55

Slide 55 text

amazon-pay対応 amzn/amazon-pay-sdk-php psr/log amzn/amazon-pay-sdk-php/AmazonPay/Client.php

Slide 56

Slide 56 text

amazon-pay対応 amzn/amazon-pay-sdk-php psr/log amzn/amazon-pay-sdk-php/AmazonPay/Client.php vendor/composer/autoload_psr4.php

Slide 57

Slide 57 text

amazon-pay対応 app/patch/Psr/Log/LoggerAwareInterface.php

Slide 58

Slide 58 text

amazon-pay対応 app/patch/Psr/Log/LoggerAwareInterface.php composer.json

Slide 59

Slide 59 text

amazon-pay対応 vendor/composer/autoload_psr4.php app/patch/Psr/Log/LoggerAwareInterface.php composer.json

Slide 60

Slide 60 text

バージョンアップの歴史 1. 苦労しながら倒したヤツら 2. 工数を減らすための工夫 3. まとめ 4.

Slide 61

Slide 61 text

ひたすら倒していくフェーズ 動作確認フェーズ の2つのフェーズに分けて紹介

Slide 62

Slide 62 text

ひたすら倒していくフェーズ

Slide 63

Slide 63 text

並行して作業し、知見の共有をしつつ進める それぞれが別のリポジトリを対応する中で当たったエラー などを共有できるので、対応方法で悩む回数を減らせる

Slide 64

Slide 64 text

エラー対応したら、すぐにリリース バージョンアップ作業で対応したエラーなどは、バージョ ンアップ用のブランチにマージせずに、本番環境にリリー スする 前のバージョンにリリースしても、基本的に動作する バージョンアップブランチと、mainブランチのdiffが小さ くなるので、バージョンアップによる影響が最小限になる

Slide 65

Slide 65 text

動作確認フェーズ

Slide 66

Slide 66 text

動作確認フェーズ 最初は機能を一覧化して、エンジニア全員でポチポチしてた 大変。。。

Slide 67

Slide 67 text

バージョンアップ前後の環境のHTMLを比較 対象のURLを一覧化 2つの環境にcurlでアクセスし、HTMLを取得 diffを取って、一致していればOKとする これを一括で行うシェルスクリプトを作成

Slide 68

Slide 68 text

バッチを一括で実行し、バッチの確認の簡略化 バッチの実行コマンドを列挙したシェルスクリプトを作成 実行結果をファイルに吐き出して、結果を確認

Slide 69

Slide 69 text

バッチを一括で実行し、バッチの確認の簡略化 バッチの実行コマンドを列挙したシェルスクリプトを作成 実行結果をファイルに吐き出して、結果を確認 ファイルの内容を解析して、エラーなく終了したということも 出力できるようにする予定 エラーを見落としたので、、、

Slide 70

Slide 70 text

バージョンアップの歴史 1. 苦労しながら倒したヤツら 2. 工数を減らすための工夫 3. まとめ 4.

Slide 71

Slide 71 text

まとめ バージョンアップにも銀の弾丸はないので、愚直にエラー を解消していく ビッグバンリリースにならないように、こまめにリリース 動作確認は自動化して楽をする けど適切にしないとミスる バージョンアップするとみんな嬉しい!

Slide 72

Slide 72 text

おわり MySQLの8化も待っている。。。