コントローラ

コントローラとは?

コントローラは、URL を通じてアクセス可能なクラスです。リクエストを処理することができます。 コントローラはモデルや他のクラスを呼び出して情報を取得します。最終的に、出力用にビューにすべてを渡します。 www.yoursite.com/example/index という URL がリクエストされた場合、1 番目のセグメント ("example") は呼び出されるコントローラで、2 番目のセグメント ("index") は、 呼び出されるそのコントローラのメソッドです。

コントローラを作成する

FuelPHP では、コントローラーは fuel/app/classes/controller ディレクトリに置きます。そして "Controller_" というプレフィックスを付けます。 必要に応じて Controller class を拡張する必要があります。 以下は "example" コントローラの例です:

class Controller_Example extends Controller
{

	public function action_index()
	{
		$data['css'] = Asset::css(array('reset.css','960.css','main.css'));
		return Response::forge(View::forge('welcome/index'));
	}
}

URL を通じてリクエストされたメソッドは、"action_" というプレフィックスを付けます。 これは PHP により使用する名前が制限を受けないことを意味します(例: "list" メソッドは許可されていないが、"action_list" は問題ない)。 しかし、これはコントローラに公開メソッドを与えることができることも意味します。 このメソッドは他のクラスからも使用できますが、ルーティングできません。

HTTPメソッド名をアクション名の前につける

HTTPメソッド名をアクション名の前につけることもできます。以下の例を見て下さい:

class Controller_Example extends Controller
{
	public function get_index()
	{
		// ここは HTTP メソッドが GET の時に呼び出されます
	}

	public function post_index()
	{
		// ここは HTTP メソッドが POST の時に呼び出されます
	}
}

サブディレクトリ内のコントローラ

fuel/app/classes/controller/subdir/test.php のように、サブディレクトリに コントローラを配置することもできます。この例では、コントローラはディレクトリ名を含む このようなクラス名にする必要があります: Controller_Subdir_Test

無制限の入れ子にされたサブディレクトリをサポートしますので、 fuel/app/classes/controller/subdir1/subdir2/subdir3/test.php はクラス名が Controller_Subdir1_Subdir2_Subdir3_Test になります。

コントローラの名前空間

冒頭で述べた通りコントローラは app/classes/controller 置かれ、 そして Controller_というプレフィックスを付けます。このプレフィックスはあなたの設定ファイル app/config/config.phpで、 (この設定がデフォルトでは存在しなかったとしても)設定されます。 あなたがコントローラに名前空間を使用したい場合、もしくはコントローラを別のフォルダへ移動させたい場合に、この設定を変更することができます。

では、前述のとおり名前空間 Controller へ expample コントローラを移動させましょう。 アプリケーションの config.php の中の controller_prefix'Controller\\' へ設定することで、この変更を FuelPHP へ知らせます。

namespace Controller;

class Example extends Controller
{

	public function action_index()
	{
		$data['css'] = Asset::css(array('reset.css','960.css','main.css'));
		return Response::forge(View::forge('welcome/index'));
	}
}

URL からの複数のパラメータの使用

例えば、Controller_Example の中に次のメソッドがあるとします:

public function action_name_to_upper($name_1, $name_2)
{
	$data['name_1'] = strtoupper($name_1);
	$data['name_2'] = strtoupper($name_2);
	return View::forge('test/name_to_upper', $data);
}

www.yoursite.com/example/name_to_upper/fuel/php を使用してこのメソッドを呼び出す場合、 test/name_to_upper ビューを返します。"FUEL" や "PHP" は $data 配列内の $name_1$name_2 という値として渡されます。

結果を返す

理想的には、コントローラアクションは Response オブジェクトを返すべきです。オプションで、特別な HTTP ヘッダや、 カスタムの HTTP ステータスコードを指定できます ("200 OK" 以外のコード)。もし、Respose オブジェクトを返さない場合、デフォルトの after() メソッドがアクションの返り値を Response オブジェクトでラップします。

あなたのコントローラがベースコントローラの 1 つを継承しているなら、アクションは文字列にキャストできる任意の値、 例えば、View オブジェクト、を返すことができます。ベースコントローラの after() メソッドがそれを Response オブジェクトに変換します。

もし、あなたのコントローラがベースコントローラの 1 つを継承していない場合で、この機能を使いたい場合、, あなたのコントローラは、アクションの返り値を受け入れ、 返されるべき Response オブジェクトにラップする独自の after() メソッドを含む必要があります。

特殊なコントローラのメソッド

クラスのコンストラクタ __construct() をオーバーライドしないでください。 代わりに before() メソッドを使用します。 まず始めにコアからベースコントローラを学習しない限り、どのように Fuel を壊さないように継承するかを理解できません。

action_index()

このメソッドは、コントローラが2番目のパラメータを指定しない場合に呼び出されます。 上記の例では、www.yoursite.com/example/index は、 www.yoursite.com/example と同じになります。

before()

before() メソッドは、コントローラのメソッドが呼び出される時に、その手前で何らかの処理をしたいときに使用します。 コントローラが URL から適切なメソッドを選びそれを呼び出す前にこのメソッドは呼ばれます。 このメソッドをルーティングの目的のために使用してはいけません。 そのためには router を使用して下さい。

after($response)

このメソッドは、URL からメソッドが正常に呼ばれた 後で 実行され、 メソッドが存在しない場合は実行されません。$response パラメータが必要です。 after() メソッドは Response オブジェクトを返さねば なりません

If the after() method has to construct a Response object, it can use the response_status property of the controller to set the HTTP status of the response. By default, this property contains "200" (OK).

router($method, $params)

このメソッドはコントローラの内部ルーティングを上書きします。 コントローラが読み込まれると、router() メソッドが呼び出されデフォルトメソッドの代わりに、 渡された $method を使用します。 $method に配列として $params で渡すこともできます。before() や after() メソッドは期待したとおりに動作します。

他のコントローラを継承する

オートローダのお陰で、クラス定義で名前以外のものを記述しないで 他のコントローラを継承できます:

class Controller_Example extends Controller_Welcome
{

	// あなたのメソッド

}

これは最初はおかしく感じるかもしれません。しかし、コントローラを継承することで、簡単にメソッドを共有し、 実際のベースコントローラを生成できます。

ベースコントローラを生成する

ベースコントローラは、Controller_Public または Controller_Admin のような共有コントローラです。各コントローラ間でロジックを共有するために使用します。 例えば、Controller_Admin コントローラは login/logout アクションを持つことができます。または dashboard も持ちます。しかし、ユーザが管理者としてログインされているかどうかをチェックする before() メソッドを含むこともできます。 他のすべてのコントローラは管理者パネルでこれを継承し、自動的に安全になります。

class Controller_Admin extends Controller
{

	public function before()
	{
		// 管理者かどうかチェック
	}

	// あなたのメソッド

	public function action_index()
	{
		// ダッシュボードをロード
	}

	public function action_login()
	{
		// ユーザをログイン
	}
}

このコードは fuel/app/classes/controller/admin.php にあり、他のコントローラはすべて fuel/app/classes/controller/admin/ にあります。次のようになります:

class Controller_Admin_user extends Controller_Admin
{

	public function action_index()
	{
		// ダッシュボードをユーザの一覧でオーバーライドする
	}

	public function action_edit($id)
	{
		// ユーザの編集
	}
}