社内基幹システムのバージョンアップに挑んだ話


こちらは [Fusic Advent Calendar 2019 - Qiita](https://qiita.com/advent-calendar/2019/fusic) 5日目の記事です。
昨日は @NaoyaMiyagawa による[S3オブジェクトレベルのログ記録+監視方法](https://qiita.com/NaoyaMiyagawa/items/48a217356fae197eb3d0) でした。
ログと監視は大事ですよね～。

ということで、こんにちは。早﨑です。
毎度のことですが時間の流れが速く、気づけばもう年の瀬ですね。
1年を振り返ると今年も業務システムをガッツリやってました。

早速ですが今年は弊社の基幹システムのバージョンアップをした話を書こうと思います。

## 弊社の基幹システムとは？

ざっくり機能を上げると

- お取引をさせていただいてる企業・案件・見積・請求・入金データの管理機能
- 社員一人一人の工数管理機能
- 各種集計出力機能
- 社内回覧機能
- 社員管理機能
- 各種マスタ

等々を持ったシステムです。

![top.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25290/11d514e3-f6be-9a2b-ca30-c689277f946a.jpeg)
これは工数入力画面

これらCakePHP3の出た当初に作成しました。（4年くらい前）
PHPのバージョンも古く5.6
JSもjqueryで。。。

上げ始めたらキリがないです:sob:

CakePHP3が出たはじめの頃でEntityとは何ぞや？右も左も良く分からないまま実装したためカオスなコードを書いています。
テストコードもホボ無いという状況です。


# 一念発起してやった

その前に何から手を付けようかと考えました。
思いつきベースでやりたいことを貯めていたのですが、全部は無理。
社内から遅いと声が上がっていたので、まずは最低限のPHPとCakePHPを上げようということで社内各方面で相談しながら何をやるかを決めました。

最終的には、PHPとCakePHPのバージョンを上げる。となりました。

- PHP5.6 → 7.3系へ
- CakePHP3.1 → 3.8系へ

PHPはサポートも切れてますし、速度面でもPHP7には劣ります。
CakePHP4を見据えて最新化することを目指しましょうという感じですね。

ということで次にどういう手順でやるかを考えました。

## 順番
- 1.開発環境をPHP7.3系で構築（本番環境も併せて検討）
- 2.システムを設置しとりあえず動くところまで持っていく
- 3.非推奨関数の置換
- 4.リファクタ
- 5.テスト
- 6.本番リリース

# やってきます

### 1.ローカルにPHP7.3系の環境を構築（本番環境も併せて検討）

対象のシステムはdocker環境で運用されています。
しかし私のローカルはvagrant、本番では基幹システム用のimageを作ることが必須となるのでこれを期に開発環境もdockerにしました。
（docker難しい。。。）


### 2.システムを設置しとりあえず動くところまで持っていく

git cloneしcomposer install！が動きません。
composerで入るプラグインが入りませんｗ
PHPのバージョンが新しくプラグインのバージョンを上げてくださいと言われました。
上げてプラグインをインストール。

で、ブラウザを叩きます。
画面はホワイトアウトです。

感の良い方は分かると思いますがCakePHP3.3からMiddlewareが導入されています。
ディレクトリやファイルの中身が若干変わっています。
Cake3.8系をcloneしWinMergeを使いながら3.1と比較しながら書き直していきました。

修正してはdumpを吐いてどこまで来ているかのチェックの繰り返しです。
かなり骨が折れました。

### 3.非推奨関数の置換

CakePHP3.8に上げたことでScrutinizerがあらぶり始めました。

![02.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25290/406591e9-dab8-3a54-43b6-7302045e058a.jpeg)

↑のIssueは殆どがDeprecatedでした:joy:
動作としては非推奨を無視するように設定していたのでブラウザからのアクセスには問題は無いのですが
はやりここはきっちりと対応しておくべきでしょう。4も控えていますし。

ということで以下を変更しエラーを全て出すようにしました。

```app.php
    'Error' => [
        // 'errorLevel' => E_ALL & ~E_USER_DEPRECATED, // ← ここを
        'errorLevel' => E_ALL, // ← こうする
        'exceptionRenderer' => ExceptionRenderer::class,
        'skipLog' => [],
        'log' => true,
        'trace' => true,
    ],
```

これでエラーが見れるようになります。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25290/d2bc89e4-3ad0-7fc7-59c4-f7f9943e6d3e.png)
殆どgetter/setter（笑）

画面をポチポチしながら出てきたもの片っ端から対応します。

### 4.リファクタ

3をしながら思うわけです。

俺、なんでこんな残念なコード書いてたんだろう。。。

と

複雑な部分は一旦さておき、パッと見で修正できるレベルのものを書き換えていきます。
折角なのでtypehintも入れていきます。完全に作業の世界です。
併せてコードはcommit時にphp-cs-fixer/phpcbf/phpmdが走るようにしたので静的解析チェックをしていきます。
Scrutinizerがあったのも良かったですね。併せてチェックができて良かったです。
template（ctp）以外の全てのコードに対して修正を行えたので凄く綺麗になりました。

![05.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25290/5b32380a-bf5d-37c9-7e0a-79efdf6b2c55.jpeg)
数を消すのがとても楽しくなりますね♪


### 5.テスト

最後にテストコードを書きたい！！
と思ってましたがこの時点では出来ませんでした。
そこまでモチベーションが続かなかったです。

画面ポチポチで確認していきます。

そんなに複雑ではないから大丈夫だろうと思ってたけど、やっぱり漏れはありますね。
本番リリース後にやはり動かないんだけど。。。という事がありました。

テストコードで100％安心できるわけでは無いですが、これにより気づける事もあります。
少しでも安心できる状況を作るのが大事ですね。

### 6.本番リリース

インフラ担当者と日時、手順を相談してえいっとやりました。
特に問題は無かったです。

事前に手順を相談し認識を合わせたのが良かったと思います。

## まとめ

- 協力者を得つつ、やりたいこと・やるべきこと・やらないことを整理することが大事。
 - コードのリファクタはちょっと踏み込み過ぎてどこまでやるか悩む。
- テストは大事
 - バグは出ます。弊社基幹システムでこのシステムがバグってしまうと仕事が出来なくなります（特にバックオフィス）
 - 軽微なバグで直ぐ対応出来たもののやはりお客様のシステムだとNGですよね。
- バージョンアップは大変
 - 動かないところが多すぎて心が折れそうになる。
 - 業務の合間や盆休みを使用して行っているため数か月掛かった。

## 最後に

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">社内基幹システムのPHPとフレームワークのバージョンを上げられて満足満足</p>&mdash; tsukabo (@tsukabo) <a href="https://twitter.com/tsukabo/status/1159462204728434689?ref_src=twsrc%5Etfw">August 8, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

社内からも速くなったねーとお言葉をいただけましたし、勉強にもなりました。
やってよかったです。



さあ次はテストコードを書かねば、俺達の戦いは始まったばかりだ:muscle:


それでは、明日のアドベントカレンダーは @ya_ma23 です！
お楽しみに！