CakePHP Advent Calender 2019 最終日の記事です。
SREチームの金澤です。
2019/12/16にCakePHP4がリリースされました。
ランサーズでは、CakePHP2.10の現システムをCakePHP3に移行中ですが、
同時に、管理画面のソースを別リポジトリに分割し、
CakePHP4で新規構築するプロジェクトも進めています。
CakePHP3で開発をしていたのですが、
CakePHP4が正式リリースされたので、CakePHP4にmigrateしました。
今回、その手順を記録しておきたいと思います。
composer.jsonのCakePHP4対応
CakePHP4.0にアップグレードするためにcomposer.jsonを修正します。
案の定ですが、単純に
"cakephp/cakephp": "^4.0",
として、composer updateしても依存関係でエラーとなってしまいました。
$ php composer.phar update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.
Problem 1
- maiconpinto/cakephp-adminlte-theme 1.1.0 requires cakephp/cakephp ~3.0 -> satisfiable by cakephp/cakephp[3.0.0, ... , 3.8.7, 3.x-dev] but these conflict with your requirements or minimum-stability.
- maiconpinto/cakephp-adminlte-theme 1.1.0 requires cakephp/cakephp ~3.0 -> satisfiable by cakephp/cakephp[3.0.0, ... , 3.8.7, 3.x-dev] but these conflict with your requirements or minimum-stability.
- Installation request for maiconpinto/cakephp-adminlte-theme ^1.1 -> satisfiable by maiconpinto/cakephp-adminlte-theme[1.1.0].
$
そのため、まずcakephp/appのcomposer.jsonをベースにCakePHP4.0をインストールし、
これをベースに必要なツールを1つづつ追加していくことにしました。
結果、CakePHP用のAdminLTEがCakePHP4に対応していないことが判明しました。
(冒頭のエラーの通りですが)
AdminLTEのCakePHP4対応
CakePHP用のAdminLTE
https://packagist.org/packages/maiconpinto/cakephp-adminlte-theme
は、CakePHP3専用で、現状CakePHP4には対応していません。
そのため、Githubリポジトリ
https://github.com/maiconpinto/cakephp-adminlte-theme
をforkしてCakePHP4に対応させることにしました。
githubリポジトリのプロジェクトをcomposerで読み込む
forkしたAdminLTEをCakePHP4.0に対応させ、自社のGithubリポジトリ
https://github.com/LancersDevTeam/cakephp-adminlte-theme
で管理します。
forkしたリポジトリのcomposer.jsonのnameを変更します。
"name": "lancers/cakephp-adminlte-theme",
管理画面プロジェクト側のcomposer.jsonで、そのnameとforkしたgithubリポジトリを呼び出すように設定します。
{ "repositories": [ { "type": "vcs", "url": "git@github.com:LancersDevTeam/cakephp-adminlte-theme.git" } ], "require": { ... "lancers/cakephp-adminlte-theme": "dev-master" },
関連ツールがCakePHP4に対応するまでは、
こうやって自前でCakePHP4に対応し、githubで管理しておく必要がありそうです。
CakePHP4.0対応のPRを出す
AdminLTEのCakePHP4化についてはPRを出しておきました。
https://github.com/maiconpinto/cakephp-adminlte-theme/pull/93
※CakePHP4版はPHP7.2以上が必須になり、PHPUnitも8.3.3以上が必須になるため、
(PHP5.4やPHP5.6をサポートする)CakePHP3版との共存は難しそうです。
ので、マージされるのであれば、メジャーバージョンアップでの対応になるかも知れません。
Upgrade ToolによるMigrate
4.0 Upgrade Guideに従って、Upgrade Toolによるアップグレードを行います。
※AdminLTEのCakePHP4バージョンアップの際も利用しました。
CakePHP Upgrade Tool
4.xブランチに切り替えて、以下のコマンドを実行すると、
$ ./bin/cake upgrade file_rename templates /path/to/app/
$ ./bin/cake upgrade file_rename locales /path/to/app/
以下の変換が行われます。
・src/Template → templates
・ctp → php
・src/Locale → resource/locale
※これに伴い、app.phpのpathsの設定も変更する必要があります。
config/app.php
'paths' => [ 'plugins' => [ROOT . DS . 'plugins' . DS], 'templates' => [ROOT . DS . 'templates' . DS], 'locales' => [RESOURCES . 'locales' . DS], ],
Rector
composer.jsonにrectorを追記してインストールします。
"require-dev": { ... "rector/rector": "*" },
4.0 Upgrade Guide に記載されていた、cakeコマンドで起動する方法がうまく行かなかったので
$ bin/cake upgrade rector --rules cakephp40 src
Unknown command `cake upgrade`. Run `cake --help` to get the list of commands.
Other valid choices:
- help
- version
- i18n
- routes
- server
- console
- bake all
- bake
- migrations
- compile
rectorコマンドを直接起動しました。
$ ./vendor/rector/rector/bin/rector process src --set cakephp40
Rector v0.6.0
0/66 [░░░░░░░░░░░░░░░░░░░░░░░░░░░░] 0%
PHP Fatal error: Declaration of App\Model\Table\FaqsTable::initialize(array $config) must be compatible with Cake\ORM\Table::initialize(array $config): void in /path/to/app/src/Model/Table/FaqsTable.php on line 98
$
親クラスであるCakePHP4 CoreのTableクラスと引数、戻り値が一致しないと怒られたので
これを修正していきます。(これを自動的に修正して欲しいのですが。。)
結果、以下の修正を行う必要がありました。
public function initialize(array $config)
↓
public function initialize(array $config) : void
public function buildRules(RulesChecker $rules)
↓
public function buildRules(RulesChecker $rules) : \Cake\ORM\RulesChecker
public function validationDefault(Validator $validator)
↓
public function validationDefault(Validator $validator) : \Cake\Validation\Validator
public function beforeFilter(Event $event)
↓
public function beforeFilter(EventInterface $event)
cakephp/app のCakePHP4対応
プロジェクトの以下のディレクトリをCakePHP4に対応させる必要があります。
(PHP7.2に対応に伴う引数の変更や戻り値の型変更など)
・config
・src
・templates
・webroot
※結局、https://github.com/cakephp/app のCakePHP4対応版を上書きし、
個別の実装差分を記述し直しました。
始まったばかりのプロジェクトのため、それほど手間ではありませんでしたが
既にCakePHP3の実装が進んでいるプロジェクトは別のアプローチが必要かも知れません。
stableバージョンにしたいが。。
現状のcomposer.jsonは以下の記述があるため、CakePHP 4.x-devがインストールされます。
"minimum-stability": "dev"
stable版である CakePHP4.0.0 をインストールするにはこの記述を削除する必要がありますが、
cakephp/migrationsも削除する必要がありました。
このツールはrectorが利用しているため、完全に移行が終了してから削除したほうが良さそうです。
"cakephp/migrations": "3.0.0-beta1",
また、bakeも2.0から1.2.8までバージョンを落とす必要がありました。
"cakephp/bake": "^1.2",
bakeのバージョンを1に落とすと、さすがにCakePHP4では使えなさそうなので、まだ
"minimum-stability": "dev"
の設定は外せなさそうです。
最後に
今回、開発中のプロジェクトをCakePHP3からCakePHP4にmigrateしてみましたが、
周辺ツールがまだCakePHP4に追いついておらず、
今のタイミングで完全移行するのは時期早尚かも知れません。
ただ、ランサーズ本体のCakePHP2→4移行については、
段階的に移行しているため、できることならCakePHP2→4へジャンプアップしたいところです。
(それを実現するためには、PHPUnitの共存等も実現する必要がありますが)