コントローラー

コントローラークラスの役割

Dispatcherクラスによるリクエストの振り分けにより、URLに対応するコントローラークラスのメソッドより処理が始まります。Dispatcherは仕組みとして作ってしまえば後は意識する必要はないので、基本的にはコントローラークラスより処理が始まるというつもりで実装が可能です。

コントローラークラスの役割は、モデルクラスとビュークラスの制御です。
基本的にはコントローラーにはゴチャゴチャと処理は書かず、処理はモデルクラスに任せます。

つまりはモデルクラスのインスタンスを生成し、メソッドの実行を行います。
戻り値として受け取ったデータをビュークラスへ渡すといった感じです。

コントローラークラスの基本

とりあえずコントローラークラスを作ってみましょう。

コントローラークラスで大事な事は命名規則です。
例えば今回は"Controller"が必ず末尾につくような想定でDispatcherが作られているので、それに従います。
同じくメソッドは"Action"が必ず末尾につく想定なので、それに従います。

次のようなクラスを作ってみます。

<?php

class HogeController
{   
    public function helloAction()
    {
        echo 'Hello World!';
    }
}

?>

お決まりの「Hello World!」です。
コントローラー(クラス名)、アクション(メソッド名)はなんでもいいですが、ここではクラスが"HogeController"、アクションが"helloAction"とします。
この場合、URLは"http://www.xxx.com/hoge/hello"です。

早速ブラウザからアクセスしてみましょう。

Hello World!

ちゃんとHello World!と表示されましたか?

Dispatcherさえきちんと作ってあれば、こんな感じでクラス名・メソッド名とURLが直結します。

アクションの作成単位

もう少し実用に近い例で見てみましょう。
例えば通販サイトを例として、そのカートページのコントローラークラスを作るとします。

CartController.php
<?php

class CartController
{
    public function displayAction()
    {
        // カート内容表示処理
    }

    public function inputAction()
    {
        // 購入情報入力フォーム表示処理
    }

    public function buyAction()
    {
        // 購入処理

        // 購入処理後、記事表示画面へリダイレクト
        header('Location: http://www.xxx.com/cart/thanks');
    }

    public function thanksAction()
    {
        // 購入完了画面表示処理
    }
}

?>

アクションを4つ作成しました。
この中で性格の異なると思われるアクションが一つあるのがお分かりでしょうか。
buyActionです。

displayActionは現在カートに入っている商品の一覧表示ページ、
inputActionは発送先等の購入情報の入力フォームで、
ともにページ表示用のアクションです。
つまり、インターフェイスが存在します。

それに対してbuyActionはと言うと、フォームで購入ボタンを押した場合の処理です。
つまり、インターフェイスが存在しません。

通常、通販サイトで購入を行ったら"ありがとうございました!"的なページが表示されることが多いと思います。
なのでbuyActionの最後に、thanksActionへのリダイレクトが必要になります。

こういったインターフェイスの存在しない処理を、アクションという単位で扱うかどうかです。

以下のような作りも考えられます。

CartController.php
<?php

class CartController
{
    public function displayAction()
    {
        // カート内容表示処理
    }

    public function inputAction()
    {
        // 購入情報入力フォーム表示処理
    }

    public function buyAction()
    {
        if (isset($_POST[''buy'])) {
            // 購入処理
        }

        // 購入完了画面表示処理
    }
}

?>

購入処理と購入完了画面表示を同じアクション内でやってしまうのです。

アクションを処理単位で作成するか、
インターフェイス単位で作成するか、の違いです。
後者の場合であれば購入ロジックと購入完了画面表示ロジックという二つの処理を一つのアクションに含める形になります。

これらはどちらの手法をとってもかまわないと思います。

前者の方がメソッド単位の処理が短くなり、綺麗なソースとなるでしょう。
後者の方がメソッド数は少なくすることが出来ます。
アクションが多くなりそうな処理の場合には後者の方が全体の見通しが良くなるでしょうし、
逆の場合は後者の方が見やすくなるでしょう。

アクションの作成基準は臨機応変に決めましょう。