コネヒト開発者ブログ

コネヒト開発者ブログ

CakePHP4.1.0がリリースされたので変更点を追ってみる

こんにちは。CTOの@itoshoです。 最近stand.fmをはじめたので、よかったら聴いてみてください。

今日は週末(7/4)にリリースされたCakePHP4.1.0の変更点をBakeryやGitHubを読んでみて、個人的に「おっ」と思ったことを中心にまとめてみたいと思います。*1

なお、全ての変更点は取り上げられないので網羅的に知りたい方は公式のリリースノートをご参照ください。また、内容についてはきちんとチェックしているつもりですが、もし間違いや分かりづらい点がありましたらご指摘いただければ幸いです。

新たに追加された機能

最初に新機能についていくつか紹介したいと思います。

共通テーブル式が利用出来るようになった

個人的には今回これが一番大きな機能かなと思うのですが、ORMで共通テーブル式(CTE)が使えるようになりました。MySQL8系や他のRDBMSを使っている方には朗報ですね。*2

WITH句は以下のようにwith()メソッドとCommonTableExpressionクラスを利用することで実現出来ます。

<?php
$con = ConnectionManager::get('default');
$query = $con
    ->newQuery()
    ->with(new CommonTableExpression('cte', function (ConnectionInterface $con) {
        return $con->newQuery()->select(['col' => 1]);
    }))
    ->select('col')
    ->from('cte');

生成されるSQLはWITH cte AS SELECT 1 AS col SELECT col FROM cte;といった感じになります。

Window関数が利用出来るようになった

こちらもMySQL8系ユーザー向けの機能ですが、Window関数も利用出来るようになりました。例えば、ROW_NUMBERを利用する場合は以下のようになります。

<?php
$function = new FunctionsBuilder()->rowNumber();

OrderAsc()メソッドとOrderDesc()メソッドにクロージャを渡せるようになった

クロージャを渡すことで、以下のようなCASE WHENを用いた複雑なソート条件を設定出来るようになります。

<?php
$query = ConnectionManager::get('default')->newQuery();
$query->select(['id'])
    ->from('children')
    ->orderAsc(function (QueryExpression $exp, Query $query) {
        return $exp->addCase(
            [$query->newExpr()->add(['user_id' => 1])],
            [1, $query->identifier('id')],
            ['integer', null]
        );
    });

ちなみに、データベース周りは他にもAggregateExpressionというクラスが追加されており、表現力がかなり強力になっているように感じます。

ログメッセージに{foo}形式のプレースホルダーが利用出来るようになった

上記の形式を利用すると$contextパラメーターの値から置き換えてくれるようになったので、以下のような書き方が可能になりました。

<?php
$context = [
    'id' => 1,
    'foo' => 'bar',
];
$this->log('error: {id}', LogLevel::NOTICE, $context);

配列なんかも渡せます。地味に便利ですね。

非推奨となった機能

次に4.1系からdeprecatedとなった機能を紹介します。ここに挙げられている機能はCake5.0で廃止される予定ですので、マイグレーションガイドを読みながら早めに対応したいなと思っています。*3

or_()メソッドとand_()メソッドの廃止

今後はor()メソッドとand()メソッドを利用する必要があります。Cake3系だとor_()メソッドは利用頻度がそれなりにあるかなと思うので、変更が必要なシステムも多いかもしれません。

ServerRequest::input()メソッドの廃止

生データを文字列で取得する場合は今後(string)$request->getBody()を利用する必要があります。

whitelistというワーディングを使った機能の廃止

これは昨今のBLM運動の流れを汲んだものになり、具体的にはPaginatorComponentwhitelistという名称のオプションがallowedParametersという名称に置き換えられるなどの変更が行われています。なお、BLM運動については賛成の立場でありつつ、日本にずっと暮らしている身からすると頭では理解しながらも肌感覚としては分からないことも正直多いのですが、分からないで終わらせず歴史的背景をきちんと勉強したり、傍観者にならずきちんと当事者意識を持って今後も動向を注視したりしていく必要があると考えています。

その他気になったこと

最後にアプリケーションテンプレートや今後のロードマップを読んで、気になったことを紹介します。

デバッガーの設定でエディターを指定出来るようになった

app.php内で以下のような設定が出来るようになりました。

<?php
'Debugger' => [
    'editor' => 'phpstorm',
 ]

ここでエディターを設定しておくと(デバッグモード時に)エラー画面で表示されるエラー箇所のリンクから各エディターをURLスキームで起動出来るようになったようです。ここではPHPStromを指定していますが、VSCodeやEmacsなども指定可能です。

ちなみにデフォルトの設定をPHPStormにしたときのPRのコメントが面白かったです。

CsrfProtectionMiddlewareの設定が移動した

新規のユーザーがこのミドルウェアがどこで設定しているか分かりづらいとの理由routes.phpから Application.php移動しています。routes.phpに設定するメリット(パスのスコープ毎に設定を切り替えられる)もありつつ、テンプレートとしてはApplication.phpに置く方が直感的だなと思いました。

DIコンテナの実装は持ち越しになった

以前、DIコンテナが4.1に導入されるかもしれないという記事を書いたのですが、ロードマップを読むと4.2へ持ち越しになったようです。個人的には期待していたのですが、やはりそれだけ影響範囲が多いということでしょうか。引き続き、状況をウォッチしていきたいなと思います。

まとめ

変更点をいくつか紹介しましたが、リリースノートをざっとみてもマイナーバージョンということもあり、細かなアップデートが中心になったかなと思います。もちろん、それが悪いことではなく、フレームワークは漸進的に確実に進んでいくことがDX(Developer Experience)の向上に繋がると思うので、CakePHPの本体のアップデートに負けないように自分たちのシステムも継続的にアップデートしていければと考えています。

というわけで最後に宣伝です!コネヒトでは新しいシステムをCakePHP4で実装するなど、積極的にCakePHPを利用しています。CakePHPを利用したアプリケーション開発や日本の家族を取り巻く社会課題の解決に興味があるエンジニアの方はオンラインで構いませんので、是非お気軽にカジュアルにお話出来ると嬉しいです!

www.wantedly.com

*1:なお現時点(7/6)で"composer create project"を実行すると既にに4.1.1がインストールされるようになっています。

*2:コネヒトではMySQL5系互換のAuroraを利用しているので、恩恵を受けられるのはもう少し先になりそうです。

*3:公式ドキュメントではRectorを使ったマイグレーション方法が紹介されています。