2018/12/15 PHPカンファレンスで発表した、CakePHP1.3 → 2.8 バージョンアップに関する資料です。
2018/12/15 PHPカンファレンスCakePHP1.3 → CakePHP2.8バージョンアップhttps://www.lancers.jp/「テクノロジーで、個をエンパワーメントする」
View Slide
2018/12/15 PHPカンファレンスはじめに
2018/12/15 PHPカンファレンス現在の進捗コントローラー移行率99%
2018/12/15 PHPカンファレンス自己紹介 4氏名:金澤 裕毅出身:宮城県仙台市ランサーズSRE略歴:大学時代はネットワークを専攻Windowsパッケージ開発(C++)ASP開発(Java)&インフラ(オンプレ)SNS開発(PHP)&インフラ(オンプレ)現在はランサーズのSRE
2018/12/15 PHPカンファレンス会社概要会社名:ランサーズ株式会社設立:2008年4月従業員:約170名事業:クラウドソーシング事業https://www.lancers.jp/所在地:〒150-0002東京都渋谷区渋谷 3-10-13TOKYU REIT 渋谷Rビル 9F
2018/12/15 PHPカンファレンス6ランサーズを支える技術
2018/12/15 PHPカンファレンスAppS3ELB AppCloudFront Cloud SearchRoute53EC2instanceWebSocketErastiCacheMemcachedErastiCacheRedisAuroraReaderAuroraWriterApiELB ApiEC2EC2instanceErastiCacheRedisEC2EC2●Amazon Linux 2017.03○PHP 5.3提供の最終バージョン●PHP 5.3.29○CakePHP 1.3.6 → 2.8○PECL○PEAR○Composer●Webサーバー○Nginx●Appサーバー○PHP-FPM こっちはPythonELB WebSocketランサーズのサーバー構成
2018/12/15 PHPカンファレンスDocker for Mac(Windows)dockerexec3306 9000DockerマウントSQLクライアント 開発環境(エディタ)ターミナル●Docker for Mac(Windows)で構築○本番環境とほぼ同じ構成をDockerコンテナで再現○DockerマウントでPCとソースを共有■開発はPC上のエディタで行うAmazon ECR10.10.6.11Appランサーズ本体10.100.106.5WordPressコーポレート、ブログ10.100.51.11MySQL10.100.6.131WebSocketメッセージサービスデータ入りランサーズの開発環境
2018/12/15 PHPカンファレンスバージョンアップ決定の経緯
2018/12/15 PHPカンファレンスなぜ、バージョンアップするのか?●サポート終了○PHP 5.3■2015/11/01 1.3.21でサポート終了○CakePHP1.3■2014/08/14 5.3.29でサポート終了●バグ修正やカスタマイズを独自に行っている状態○最新バージョンであれば貢献できる内容もPHPCon福岡で宣言年末には5.6もサポート終了
2018/12/15 PHPカンファレンス●サポート終了○guzzleライブラリ■Composer 1.7.3からインストール不可○AWS SDK PHP■最新バージョン(V3)はPHP5.5以上●Amazon RekognitionもV3○顔認証に利用したかった。。○Facebook SDK■最新バージョンはPHP5.4以上●旧バージョンのサポート終了が早い■PHP5.3サポートのfork版で対応中●が、これもサポート終了○手動で修正してしがみついている状態○FireBase Admin SDK for PHP■PHP7.0以上なぜ、バージョンアップするのか?
2018/12/15 PHPカンファレンス●会社の成長フェーズの変化○技術を重視した方針が採用されやすくなった■2017年にバージョンアップを社外に宣言○PHPコミュニティにも積極参加するようになった●エンジニアに魅力のある開発環境を提供したい○生産性を上げたい■新しいPHPの関数が使えるようにしたい■新しいPHPの仕様でコーディングしたい○フリーランスが外部パートナーの開発者には死活問題●常に最新の技術やバージョンに追従したい○旧バージョンをカスタマイズしない○最新バージョンでOSSに貢献するなぜ、バージョンアップするのか?
2018/12/15 PHPカンファレンスバージョンアップ計画
2018/12/15 PHPカンファレンスバージョンアップ条件の整理PHPバージョンPHPキャッシュCakePHP対応バージョンApacheバージョンPHP5.3 APC CakePHP1.3CakePHP2Apache 2.2PHP5.4 CakePHP1.3CakePHP2Apache 2.4PHP5.5 OPCacheAPCuCakePHP1.3CakePHP2Apache 2.4PHP5.6 OPCacheAPCuCakePHP1.3CakePHP2CakePHP3Apache 2.4PHP7.0 OPCacheAPCuCakePHP2CakePHP3Apache 2.4Apacheもバージョンアップが必要CakePHP 1.3はまともに動かないCakePHP 3未サポートバージョンアップ前の構成json.soのインストールに問題最も対応しているPHPバージョンPHPとセットでインストールされる●Amazon Linux 2017.03で調査
2018/12/15 PHPカンファレンスApache + mod_php → Nginx + PHP-FPMに●PHPをバージョンアップすると、Apacheも2.2→2.4になる○Apacheの設定も作り直しが必要■それなら別の構成も検討したい●Nginx + PHP-FPMを採用○パフォーマンスの向上に期待していた■結果はレスポンス、サーバーリソース消費量もほぼ変わらず
2018/12/15 PHPカンファレンスSREチームで提案したバージョンアップ手順PHPバージョンPHPキャッシュCakePHPバージョンWebパッケージバージョン(yum)PHP5.3 APC CakePHP1.3 Apache 2.2 + mod_phpPHP5.3 APC CakePHP1.3 Nginx + PHP-FPM 5.3PHP5.6 OPCacheAPCuCakePHP1.3 Nginx + PHP-FPM 5.6PHP5.6 OPCacheAPCuCakePHP2 Nginx + PHP-FPM 5.6PHP5.6 OPCacheAPCuCakePHP3 Nginx + PHP-FPM 5.6PHP7.x OPCacheAPCuCakePHP3 Nginx + PHP-FPM 7.0Nginx + PHP-FPMに置き換えPHP 5.6まで一気にバージョンアップ最大の難関カスタマイズ問題を解決
2018/12/15 PHPカンファレンスアプリチームと相談して手順をさらに整理1.3 → 2.82.8 → 2.x 最新2.x 最新 → 3.x .. more5.3 → 5.65.6 → 7.3SRE担当アプリ担当SRE担当アプリ担当→
2018/12/15 PHPカンファレンスCakePHP1.3 → CakePHP2.8移行計画
2018/12/15 PHPカンファレンスソースコード量ファイル数 行数ビュー 約2000 約16万コントローラー 約260 約10万モデル 約280 約9万バッチ 約130 約5万UT 約500 約20万全体 約3170 約60万
2018/12/15 PHPカンファレンスバージョンアップ開始時の前提●日々のサービス開発は止められない○複数のチームで日々リリースされている●体制○専任を3人●方針○CakePHP2.8にアップデートしたブランチを作成■動作確認しながらコントローラー単位で移行●UTで互換性を保つ○CakePHP 2.8 はPHPUnit○CakePHP 1.3 はSimpleTest■CakePHP 2.8でも動くように細工
2018/12/15 PHPカンファレンス行き詰まる●毎週masterから最新を取り込み○同じような修正が多くてつらい。。。バージョンアップのための修正よりも、日々リリースされる差分吸収のコストが大きすぎて思うように進められない、、、
2018/12/15 PHPカンファレンスイノベーションが起きました!CakePHP1.3とCakePHP2.8を同居させれば徐々に移行できるんじゃない?
2018/12/15 PHPカンファレンスCakePHP1.3 → CakePHP2.8同居計画
2018/12/15 PHPカンファレンスCakePHP1.3と2.8の同居準備CakePHP1.3CakePHP2.8●共通ファイルCakePHP2.8側にもコピー○Componet○Helper○View●1コントローラーずつ移行○移行完了したものから本番リリース
2018/12/15 PHPカンファレンスコントローラー単位でCakePHP2.8にスイッチ●app/config/Letto/switch.yml○ここに設定したURIはCakePHP2.8で処理する---switched:cakephp28:…- /mypage- /mypage/- /mypage/index- /mypage/index/*- /mypage/charge- /mypage/charge/*…- /user/login- /user/login/*- /user/logout- /user/logout/*…- /work/detail- /work/detail/*…- /work/proposals- /work/proposals/*…- /work/search- /work/search/*
2018/12/15 PHPカンファレンスコントローラー単位でCakePHP2.8にスイッチ●app/webroot/index.phpif (!defined('DS')) {define('DS', DIRECTORY_SEPARATOR);}if (!defined('ROOT')) {define('ROOT', dirname(dirname(dirname(__FILE__))));}require ROOT . '/app/vendors/composers/autoload.php’;// cakephp28に切り替えif (¥L¥Cake::isSwitched()) {include ROOT . '/cake28/webroot/index.php’;return;}…
2018/12/15 PHPカンファレンスコントローラー単位でCakePHP2.8にスイッチ●Lib/Cake/Cake.phpnamespace L;use ¥Letto¥Config¥Config;class Cake{/*** 切り替え済みかどうか* - true: 切り替え済み(cakephp28)* - false: まだ(cakephp13)** @return boolean*/public static function isSwitched(){$uri = $_SERVER['REQUEST_URI'];$list = static::loadConfig()->get('switch.switched.cakephp28', array());return static::_isSwitched($uri, $list);}…private static function loadConfig(){$config = new Config(ROOT . '/app/config/Letto');$config->load('switch', 'yml');return $config;}}
2018/12/15 PHPカンファレンス同居しながら移行するメリット●コントローラ単位でリリースが可能○さらに関数単位(API単位)でもリリース可能●不具合発生時のスコープを限定できる○Revertもコントローラー単位で可能●状況に応じて他のエンジニアにも協力を求めやすい
2018/12/15 PHPカンファレンス同居しながら移行するデメリット●普段の開発でCakePHP1.3、2.8両方に修正が必要になる○Model■原則全ファイル同居○View■複数Controllerで使われるファイルは同居○Lib■namespaceを分けて同居●複数のModel、Controllerから呼び出される○etc..■Config系ファイルとか●片方に寄せて呼び出す回避方法はある●一度手を出したら最後までやめられない○途中で投げ出したら一生両方修正することに。。
2018/12/15 PHPカンファレンスバージョンアップの進め方
2018/12/15 PHPカンファレンス基本的なCakePHP1.3→2.8移行手順CakePHP1.3 CakePHP2.8$this->action $this->request->action$this->params['action'] $this->request->action$this->data $this->request->data$this->params['data'] $this->request->data$this->here $this->request->here$this->header $this->request->header$this->webroot $this->request->webroot$this->params['form'] $this->request->data$this->params['url']['url'] $this->request->url$this->params['url'] $this->request->query$this->params $this->request->params$this->RequestHandler->isXXX $this->request->is('xxx')●ControllerとViewの両方
2018/12/15 PHPカンファレンス基本的なCakePHP1.3→2.8移行手順CakePHP1.3 CakePHP2.8public $helpers = array('Form'); 削除new XxxHelper() new XxxHelper(new View())$this->Auth->allow('*') $this->Auth->allow()$this->Auth->allow(array('*')) $this->Auth->allow()cakeError('error404') return $this->_error404()'order' => array('User.id DESC')'order' => 'User.id DESC''order' => array('User.id' => 'DESC')App::import('Helper', 'Hoge'); App::uses(‘HogeHelper', 'View/Helper’);※パスの大文字小文字に注意※App::usesでレスポンス改善(遅延ローディング)●Controller
2018/12/15 PHPカンファレンス基本的なCakePHP1.3→2.8移行手順CakePHP1.3 CakePHP2.8AjaxHelper、JavascriptHelper HtmlHelper、JsHelperXmlHelper Cake/Utility/Xml$html $this->Html$session $this->Session$paginator $this->Paginator__(‘名前’, true) __(‘名前’)$this->Paginator->sort(‘名前’, name) $this->Paginator->sort(name, ‘名前’)$this->set('title_for_layout, ...) $this->assign('title', ...)$this->Html->script('/js/hoge') $this->Html->script('/js/hoge.js')$this->Form->create('User', array('action' => 'index'))$this->Form->create('User', array('url' => 'index'));※Undefined Index等のNotice ※isset等で対策●View
2018/12/15 PHPカンファレンス基本的なCakePHP1.3→2.8移行手順●Model、Lib、Entity等○find($condition)■find(‘first’, $condition)○名前空間の対応■CakePHP2.8側に別途namespaceを設定●CakePHP 1.3:Category●CakePHP 2.8:¥App¥Lib¥Entities¥Category○※usesで設定しても良い○EntityやServiceなどnamespaceが付いたクラス■DateUtilやExceptionなどを絶対参照にする■Exception → ¥Exception○Modelバリデーション■notEmpty→notBlankに変更
2018/12/15 PHPカンファレンスCircleCIの活用●CakePHP2.8の移行ができていない箇所をCircleCIでチェック○Chatworkに通知
2018/12/15 PHPカンファレンスバージョンアップ時の注意点
2018/12/15 PHPカンファレンス●CakePHP2.8移行時の大文字移行忘れ○開発環境では大文字小文字を区別しないため気づけない●Dockerの共有フォルダを利用しているために起こる問題○開発環境(Windows、Mac)共通の問題○→AWS環境での検証まで気づかない。。。●解決方法○→CircleCIで検知$this->render('/work/detail_client');$this->render('/Work/detail_client');開発環境は大文字にし忘れてもエラーにならない大文字小文字問題
2018/12/15 PHPカンファレンス●CakePHP1.3と2.8でCacheのキーの扱いが異なる○Cache::read(‘MyThanks.000_111_user’)■CakePHP1.3:’my_thanks_000_111_user’■CakePHP2.8:’mythanks_000_111_user’○キーをキャメルケース → スネークケースに変更して対応■→これもCirceCIで検知キャッシュのキー問題
2018/12/15 PHPカンファレンス●find関数の取得結果が1件もない場合○CakePHP1.3 → false○CakePHP2.8 → array(0)○以下のコードの判定結果がtrueになってしまう■if ($this->Work->find ($query)) {●query関数の取得結果が1件もない場合○↑と同様○以下のコードの判定結果がtrueになってしまう■if ($this->Work->query($updateQuery)) {●tinyint(1) カラムの取得結果○CakePHP1.3 → そのまま数値○CakePHP2.8 → false or true■処理の過程でnull or 1になることも●(int)等で数値変換が必要ORM関連
2018/12/15 PHPカンファレンス●find関数でcontainとfieldsを両方指定○CakePHP1.3■contain対象のfields指定は不要●しなくてもすべてのカラムを取得○CakePHP2.8■contain対象にもfields指定が必要●指定しないとidカラムしか取得されない○※ containの指定が2階層以降だと発生する■1階層なら挙動の違いはなさそうORM関連
2018/12/15 PHPカンファレンス●CSRFエラー○CakePHP2.8→Cake1.3のコントローラーをまたぐPOST処理■両方のコントローラー(関数)を同時に移行する必要がある●Authエラー○複数Submit■フォーム改ざんチェックの項目●表示時のURLとPOST時のURLが一致すること■複数のSubmitでjsで動的にURLを書き換えていると通らない●確認画面で送信をしても更新されない○リクエストではなくセッションでデータを持ち回しているケース■リクエスト時は空POST●コントローラーの条件分岐で弾かれる○cake13の場合はTokenがPOSTに含まれていた。。●他。。(パターンたくさん)Security Component対応
2018/12/15 PHPカンファレンス長丁場を闘うために
2018/12/15 PHPカンファレンス43SRE専任1人アプリ専任3人次々と他PJに駆り出されるSREチーム参戦新卒も巻き込み総力体制2017/2 プロジェクト始動2017/6 Nginx + PHP-FPM化2017/7 CakePHP1.3→2.8化開始2017/12 CakePHP同居体制開始2018/22018/42018/52018/7 バッチ、管理画面開始2018/112018/12バージョンアップチームの変遷SREチーム2人体制
2018/12/15 PHPカンファレンスノウハウのシェア●バージョンアップ手順、ノウハウをGitHub Wikiにまとめてシェア○途中参入したエンジニアがすぐに適用できる体制にしておく
2018/12/15 PHPカンファレンス動作確認の効率化●CircleCIの活用○PSRチェック○CakePHP2チェック●Dockerの活用○データ入りのMySQLコンテナで開発■docker commitで現在の状態を保存●データ更新後にすぐ戻せるようにしておく
2018/12/15 PHPカンファレンス●やること○不要なソースの削除■使われていないファイルや関数を削除する○Notice、Warning撲滅●やらないこと○リファクタリング■どうしてもしたくなるが、敢えてやらない●バージョンアップを優先●レビュー負荷をできるだけ軽くするやること/やらないことを明確にする
2018/12/15 PHPカンファレンス動作確認の効率化●ステップ実行機能の活用○CakePHP1.3とCakePHP2.8の挙動を比較■変数の内容をリアルタイムに確認可能○設定方法■PHPStorm●https://qiita.com/yKanazawa/items/363ba93f8a376c5b9e75■Visual Studio Code●https://qiita.com/yKanazawa/items/21881b060215c01243d6
2018/12/15 PHPカンファレンス進捗の見える化●移行進捗リストの作成○コントローラー単位で作業者と進捗を見える化2018/2 2018/8 2018/11
2018/12/15 PHPカンファレンス進捗の見える化 49●2018/4~2018/5○SREチーム参戦~総力体制の構築新規開発がCakePHP1.3で行われていた
2018/12/15 PHPカンファレンス進捗の見える化 50●2018/6~2018/11○重いコントローラーを後回しにしていたためペースが落ちる99%
2018/12/15 PHPカンファレンス今後の展望
2018/12/15 PHPカンファレンス今後の展望●まずはCakePHP2.8移行を終わらせる○最後のControllerを完了させる■9000ステップ○コントローラー移行率100%後の作業■CakePHP1.3の削除●View●Model●Lib他●スイッチャーの削除○CakePHP2.8ベースで動作させる■ディレクトリの移動●tmp●logs●vendor●composer●webroot○nginxの設定変更が必要
2018/12/15 PHPカンファレンス今後の展望●PHP5.6化○APC→OPCacheによる高速化○新しい構文が使えることによる開発の高速化○SDKのバージョンアップ■AWS SDK V3■FaceBook SDK最新版●PHP7化○さらなる高速化○すべてのSDKが使えるようになる■FireBase Admin SDKも●CakePHP3化○PHP 7.2 + CakePHP 2.10まで終わってから考える
2018/12/15 PHPカンファレンス最後に
2018/12/15 PHPカンファレンスエンジニア絶賛募集中!●弊社HP、Wantedlyからご応募ください
2018/12/15 PHPカンファレンスご清聴ありがとうございました!