CakePHP 4 で一部のコントローラを別フォルダに設置する方法

はじめに
CakePHP 4 は MVC モデルが採用されているフレームワークで、各種ファイルを格納するフォルダが明確にされています。
また CakePHP 4 には Ajax や Web API 用の機能も充実しているのですが、それらの機能も通常のアクションと同じように Controller に書きます。
例えば通常のアクションと Ajax 用アクションが共存するシステムの場合、コントローラの肥大化防止策としてファイル分割が考えられます。
しかし、次の悩みとして Controller フォルダ内のファイルが増えてしまい、作業効率が低下する可能性が出てきます。
そこで今日は CakePHP 4 で一部のコントローラを別のフォルダに設置する方法をご紹介します。
/src/Controller フォルダの移動ではなく、コントローラの一部を別フォルダに移動です。
動作確認に使用したのは CakePHP 4.1.5 (cakephp/app 4.1.1) です。
1. 下準備
今回は Ajax 専用コントローラを作るケースを想定し、
下記のように /src/Ajax にそれらを置くことにします。
/path/to/cakephp4/
├ src/
│ ├ Ajax/
│ │ ├ AppController.php
│ │ └ SampleController.php
(他省略)
上記の AppController.php は /src/Ajax/ に置く各クラスで継承するもので、ファイル名は変更しても差支えありません。
(これを使わない方法も含め、詳細は後述します)
また、今回ご紹介する方法の概要を以下にまとめます。
- /src/Ajax に設置するコントローラの namespace は /App/Controller/Ajax にする
- /composer.json で上記 namespace のディレクトリを指定
- /src/Ajax にコントローラ作成
- /config/routes.php でルーティング設定
2. composer.json に namespace と フォルダの設定追加
composer.json の autoload に、下記のように追記します。
"autoload": {
"psr-4": {
"App\\": "src/", ← 末尾の , 追加を忘れずに
"App\\Controller\\Ajax\\": "src/Ajax/" ← これを追加
}
},
追加したら下記コマンドで autoload ファイルを更新します。
$ cd /path/to/cakephp4
$ composer dump-autoload
追記した内容が反映されるファイルは
/vendor/composer/autoload_psr4.php と 同 autoload_static.php です。
- PSR-4 (The composer.json schema - Composer)
- https://getcomposer.org/doc/04-schema.md#psr-4
- dump-autoload (dumpautoload) (Command-line interface / Commands - Composer)
- https://getcomposer.org/doc/03-cli.md#dump-autoload-dumpautoload-
3. コントローラ設置
/src/Ajax に置くコントローラは下記のようにしました。
どちらも namespace が App\Controller\Ajax ですのでご注意ください。
<?php
declare(strict_types=1);
namespace App\Controller\Ajax;
use Cake\Controller\Controller;
class AppController extends Controller
{
}
<?php
declare(strict_types=1);
namespace App\Controller\Ajax;
class SampleController extends AppController
{
public function index()
{
$this->set('message', 'これはサンプルです');
$this->viewBuilder()
->setClassName('Json')
->setOption('serialize', ['message'])
->setOption('jsonOptions', JSON_FORCE_OBJECT);
}
}
Ajax/AppController は、通常の Controller/AppController に合わせて同じ名前にしていますが、別な名前に変えていただいても差し支えありません。
(その際は SampleController の extends の箇所も変更してください)
この Ajax/App... を作らずに、通常の Controller/App... を継承しても良かったのですが、「こんなこともできる」という意味も含めて、このような形でご紹介しました。
僕は Ajax/App... を用意すると Ajax 用コントローラだけの共通処理を書くときに便利だと思っています。
もう一方の SampleController は JSON を返すプログラムです。
詳しくは過去記事「CakePHP 4 で JSON 出力を実装する方法」をご参照ください。
もし /src/Controller/AppController.php を継承したい場合は、下記のようにすれば対応可能です。
// ↓ 通常の AppController を継承する場合
use App\Controller\AppController;
class SampleController extends AppController
4. ルーティング設定
/src/Ajax に配置したコントローラへのルーティング設定を行います。
下記サンプルは https://example.com/ajax/sample のような形でアクセスできるようにしています。
$routes->scope('/', function (RouteBuilder $builder) {
// ↓ 追加
$builder->connect('/ajax/{controller}', ['prefix' => 'Ajax']);
...
}
作業はこれで完了です。
動作確認として、ブラウザで /ajax/sample にアクセスし JSON でメッセージが表示されるか確認してみてください。
ルーティング設定については CakePHP 4 の公式ドキュメントに様々な事例が紹介されていますので、参考にしながら適宜変更していただければと思います。
- Routing (CakePHP 4.x Cookbook)
- https://book.cakephp.org/4.next/en/development/routing.html
5. おわりに
適切なファイルの分割や配置は、作業効率の向上やストレス軽減に繋がります。
特にコントローラが大きかったり、ファイル数が多いプロジェクトでは、こういう小さな改善が効いてくるなと感じます。
逆に小さなプロジェクトでは、今回のような対応はしない方が効率的かもしれません。
ところで、この形でまだ試していないことがありまして、それは Bake と 自動テスト です。
このあたりについては今後試そうと思います。