前回の『Laravelのルーティング』で、Laravelの魅力にとりつかれてしまった私は、Laravelを本格的に習得したくなってきました。本日は、Laravelのコントローラについて調べてみたいと思います。
コントローラの基本
1. Laravelのコントローラは基本的にBase_Controllerクラスを継承する必要があります。そして、Laravelが他のフレームワークと違うところは、このコントローラをルーティングで登録する必要があるということです。下記にコントローラとルーティングの記述例を記載しておきます。
laravel/application/controllers/hello.php
<?php class Hello_Controller extends Base_Controller{ public function action_index(){ return View::make('hello.index'); } }
laravel/application/routes.php
Route::controller(array('hello'));
2. 尚、『PHPフレームワークLaravelの導入』でも説明しましたが、コントローラを一つずつ登録するのが面倒な場合、Controller::detect()でアプリケーション中のcontrollersフォルダに存在する全てのコントローラをたった1行で登録することが出来ます。
3. 只、Controller::detect()メソッドでは、コントローラをロードする順番をコントロールできませんので、Controller::detect()メソッドは、とても小さなサイトに対してのみ使用すべきであると公式ドキュメントには記載されています。
コントローラルーティング
4. 下記にコントローラルーティング例の一部を記述しておきます。
laravel/application/routes.php
//アプリケーションの全てのコントローラを登録する Route::controller(Controller::detect()); //adminバンドルのコントローラを全て登録する Route::controller(Controller::detect('admin')); //ルーターにhomeコントローラを登録する Route::controller('home'); //ルーターに複数のコントローラを登録する Route::controller(array('dashobord.panel','admin'));
5. 尚、一度コントローラを登録すれば、他のPHPフレームワーク同様にメソッドには、シンプルなURI規約でアクセスすることが出来ます。
http://localhost/コントローラ/メソッド/引数
バンドルコントローラ
6. バンドルに属するコントローラを作成するのは、アプリケーションのコントローラを作成するのとほとんど同じです。只、コントローラのクラス名の前にバンドル名を付ける必要があります。それでは、前回作成したbundlesのadminフォルダにcontrollersフォルダを作成し、その中にhomeコントローラを作成してみましょう。
laravel/bundles/admin/controllers/home.php
<?php class Admin_Home_Controller extends Base_Controller{ public function action_index(){ return 'bundles/admin/homeコントローラのindexアクションです'; } }
7. そしてルーターにバンドルのコントローラを登録します。
laravel/application/routes.php
//Adiminバンドルのhomeコントローラを登録する Route::controller('admin::home');
8. ブラウザで表示してみます。
Laravelのルーターでバンドルコントローラを登録するには、バンドル名::コントローラ名で指定します。
アクションフィルター
9. アクションフィルターはコントローラアクションの前後に実行できるメソッドです。 "before"と"after"フィルターをコントローラのコンストラクターの中で、コントローラアクションと結びつけることも可能です。
10. それでは実際に試してみましょう。前回作成したhelloコントローラを下記のように修正します。
laravel/application/controllers/hello.php
<?php class Hello_Controller extends Base_Controller{ //コンストラクター function __construct(){ parent::__construct(); //全てのアクションに'auth'フィルターを適用する $this->filter('before','auth'); } public function action_index(){ echo "Indexアクションです"; } public function action_list(){ echo "listアクションです"; } public function action_add(){ echo "addアクションです"; } public function action_posts(){ echo "postsアクションです"; } }
11. 'auth'アクションは、Laravelのroutes.phpに最初から備わっています。下記に記述しておきます。
laravel/application/routes.php
Route::filter('auth', function() { if (Auth::guest()) return Redirect::to('login'); });
12. authフィルターは、そのユーザーがログインしていることを確認し、していない場合は'login'へリダイレクトするのですが、Loginコントローラを作成していないので、このままでは、エラーになります。Loginコントローラを下記のように作成します。
laravel/application/controllers/login.php
<?php class Login_Controller extends Base_Controller{ public function action_index(){ echo "ログインページです"; } }
13. 例のごとく、Loginコントローラをルーターに登録します。
laravel/application/routes.php
Route::controller(array('hello','home','login'));
14. ブラウザでhelloコントローラにアクセスしてみましょう。下記のようにloginコントローラへリダイレクトされました。
http://localhost/laravel/public/hello
上記のHelloコントローラで作成した、全てのアクションでアクセスしても、Loginコントローラへリダイレクトされます。又、上記以外の存在しないアクションでアクセスしてもエラーは表示されず、Loginコントローラへリダイレクトされます。
15. いくつかのアクションにだけフィルターを適用するには、onlyメソッドを使います。上記Helloコントローラの6~7行目を下記のように変更します。
laravel/application/controllers/hello.php
//index、listアクションにのみ'auth'フィルターを適用する $this->filter('before','auth')->only(array('index','list'));
16. ブラウザで確認してみます。左のフィルターが適用されているアドレスだけリダイレクトされました。
17. いくつかのアクションを除いた全てにフィルターを適用するには、exeptメソッドを使います。上記の2行を下記のように変更します。
laravel/application/controllers/hello.php
//add、postsアクション以外に'auth'フィルターを適用する $this->filter('before','auth')->except(array('add','post'));
挙動は、上記15のonlyメソッドとほとんど変わりませんので、ブラウザの表示はしません。只、上記のonlyメソッドとの違いは、onlyメソッドは存在しないアクションが指定された場合、404エラーが発生します。404エラーは、実際の運用時には表示しないように設定すればいいのですが、onlyメソッドで記述漏れがあるとアクセスさせたくないページへアクセスされる可能性もあります。ですので、onlyメソッドを使うより、このexceptメソッドを使って、認証しなくてもアクセスできるページを記述した方が、セキュリティリスクは減ると思います。
18. Laravelは特定のHTTP変数(POST,GET,PUT,DELETE)にのみ、フィルターを適用するにはonメソッドを使います。下記に例を記述しておきます。
//POSTに対してフィルターを適用する $this->filter('before','csrf')->on('post');
19. CSRFフィルターは他のシステムからのポストを防ぐように設計されており、Laravelには、デフォルトで用意されています。LaravelのCSRFフィルターについては後日調べてみたいと思います。 尚、routes.phpには標準でルーティングされていますので、下記に記述しておきます。
laravel/application/routes.php
Route::filter('csrf', function() { if (Request::forged()) return Response::error('500'); });
コントローラのネスト
20. コントローラはメインのcontrollersフォルダの下に、好きなだけサブフォルダーを作成し、その中に置くことも出ます。
21. ネストしたコントローラの指定は『スラッシュ(/)』では無く、『ピリオド(.)』を使います。
laravel/application/routes.php
//controllers/admin/panelを指定 Route::controller('admin.panel');
23. 尚、ネストしたコントローラを使用する場合、ネストの深いものから浅いもの順にルーターに登録します。
RESTコントローラ
24. Laravelは、コントローラのアクションを'action_'ではじめる代わりに、対応させたいHTTP変数名を付ける事も出来ます。尚、そのときには、RESTFULプロパティを設定する必要があります。下記に記述例を記載しておきます。
laravel/application/controllers/hello.php
<?php class Hello_Controller extends Base_Controller{ //RESTFULプロパティの設定 public $restful=true public function get_index(){ //ここにコードを記述 } }
本日のブログは、Web職人のためのフレームワークのコントローラの項目を検証いたしました。検証が間違っている可能性もありますので、必ず、公式ドキュメントを一読下さい。
次回は、『Laravelのビュー』について調べみたいと思います。
本日は以上です。