複数処理のコントローラクラス
無事コントローラクラスが動作したところで、もう一度リスト3を見てください。前回までのサンプルと違い、非常にすっきりとしたルーティング登録ファイルとなっています。ただ、これでもまだ問題があります。その確認と解決方法を見ていきましょう。
__invoke()を使わないコントローラクラス
リスト1で記述したコントローラクラスというのは、リクエスト処理1つにつきコントローラクラスを1つ作成し、そのクラスの__invoke()メソッドにリクエスト処理を記述するものでした。この方式で確かにルーティング登録ファイルはすっきりします。しかし、リクエスト処理数が増えればそれだけクラス数が増え、それはそれでメンテナンス性が下がります。
そこで、ある程度リクエスト処理をひとまとめにし、例えば会員管理や受注管理といった機能ごとに1つのコントローラクラスとし、各リクエスト処理をそのクラスのメソッドとして記述する方法がSlimにはあります。それは、例えば、リスト5のクラスとなります。
<?php namespace CodeZineSlim\FirstSlim\controllers\no6; // (1) use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ResponseInterface as Response; use Psr\Container\ContainerInterface; class Chap6Controller // (2) { private $container; // (3) public function __construct(ContainerInterface $container) // (3) { $this->container = $container; } // (4) public function helloNatsume(Request $request, Response $response, array $args): Response { $assign["name"] = "夏目"; $view = $this->container->get("view"); return $view->render($response, "no4/helloWithVals.html", $assign); } // (5) public function helloAkutagawa(Request $request, Response $response, array $args): Response { $assign["name"] = "芥川"; $view = $this->container->get("view"); return $view->render($response, "no4/helloWithVals.html", $assign); } }
名前空間の付け方(1)、クラス名の付け方(2)、コンストラクタの記述方法と役割、および、プロパティの役割(3)については、リスト1で紹介した__invoke()を使ったコントローラクラスと同じです。違いは、(4)と(5)です。
リクエスト処理を記述するメソッドとしては、__invoke()を使わずに通常のメソッド同様に任意のメソッド名を記述できることが挙げられます。メソッド名を任意にできるだけで、引数と戻り値については、__invoke()と同じです。
リスト5の(4)では、第4回のリスト6と同じ処理である、画面に「こんにちは!夏目さん!」と表示するようにコードを記述したメソッドとしてhelloNatsume()を記述しています。(5)では「夏目さん!」を「芥川さん!」に変えたhelloAkutagawa()を記述しています。
コントローラクラス内メソッドのルーティング登録
次に、このようにして記述したメソッドを、ルーティング登録しましょう。routes6.phpにリスト6の太字の部分を追記してください。
<?php use CodeZineSlim\FirstSlim\controllers\no6\HelloController; use CodeZineSlim\FirstSlim\controllers\no6\Chap6Controller; // (1) $app->any("/no6/helloWithInvokableController", HelloController::class); $app->any("/no6/helloNatsume", Chap6Controller::class.":helloNatsume"); // (2) $app->any("/no6/helloAkutagawa", Chap6Controller::class.":helloAkutagawa"); // (3)
リスト5で作成したChap6Controllerクラスをルーティング登録で使用するので、useで事前にクラスを読み込んでおきます。それが、リスト6の(1)です。
その上で、ルーティング登録の第2引数に以下の書式のコードを記述します。
コントローラクラス名::class.":メソッド名"
それが、(2)と(3)です。(2)では「夏目さん!」と表示する処理を/no6/helloNatsumeのルーティングパターンとしてリスト5の(4)のhelloNatsume()メソッドを登録します。その記述が
Chap6Controller::class.":helloNatsume"
です。ここで注意したいのは、メソッド名の部分に()の記述は不要な点です。
「芥川さん!」と表示する処理についても同様で、リスト6の(3)のように
Chap6Controller::class.":helloAkutagawa"
と記述します。
コードが記述できたところで、動作確認をしておきましょう。以下のURLにアクセスしてください。
- http://localhost/firstslim/src/public/no6/helloNatsume
図3の画面が表示されれば成功です。
同じく、以下のURLにアクセスしてください。
- http://localhost/firstslim/src/public/no6/helloAkutagawa
図4の画面が表示されれば成功です。
最後に、コントローラクラスのメソッドをルーティング登録する構文を、ルーティング登録メソッドany()を例にまとめておきます。
$app->any(ルーティングパターン, コントローラクラス名::class.":メソッド名");
まとめ
今回は、Slimにおいてルーティング処理を1つのクラスにまとめておく方法として、コントローラクラスを紹介しました。
次回は、途中のNoteでも紹介したように、Slimを使ったアプリ内で実行エラーが生じたい場合に、そういったエラーを扱う方法としてエラーハンドラを紹介します。