イントロダクションIntroduction
全リクエストの処理をたった一つのroutes.phpファイルで定義するより、コントローラークラスを使い構造化して利用したいと思われるでしょう。コントローラーは関連したHTTPリクエストのロジックをクラスにまとめます。基本的にコントローラーはapp/Http/Controllers
ディレクトリーに設置されます。Instead of defining all of your request handling logic in a single routes.php
file, you may wish to organize this behavior using Controller classes. Controllers can group related HTTP request handling logic into a class. Controllers are typically stored in the app/Http/Controllers
directory.
基本的なコントローラーBasic Controllers
コントローラークラスの一例です。Here is an example of a basic controller class:
<?php namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
class UserController extends Controller {
/**
* 指定されたユーザーのプロファイルを表示する
*
* @param int $id
* @return Response
*/
public function showProfile($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
コントローラーアクションへのルートは、次のように書くことができます。We can route to the controller action like so:
Route::get('user/{id}', 'UserController@showProfile');
注目: 全てのコントローラーはベースコントローラークラスを拡張する必要があります。Note: All controllers should extend the base controller class.
コントローラーと名前空間Controllers & Namespaces
とても重要な注目ポイントは、コントローラーの完全な名前空間を指定する必要がないことです。「ルート」のApp\Http\Controllers
名前空間に続くクラス名の部分だけを指定しています。デフォルトでは、RouteServiceProvider
がルートコントローラーの名前空間を指定したルートグループの中で、routes.php
ファイルをロードします。It is very important to note that we did not need to specify the full controller namespace, only the portion of the class name that comes after the App\Http\Controllers
namespace "root". By default, the RouteServiceProvider
will load the routes.php
file within a route group containing the root controller namespace.
App\Http\Controllers
ディレクトリーより深く、コントローラのPHP名前空間をネストしたり、組織立てたりする場合でも単に、App\Http\Controllers
ルート名前空間からの相対クラス名を指定するだけです。ですから、コントローラーの完全なクラス名がApp\Http\Controllers\Photos\AdminController
ならば、次のようにルートを登録します。If you choose to nest or organize your controllers using PHP namespaces deeper into the App\Http\Controllers
directory, simply use the specific class name relative to the App\Http\Controllers
root namespace. So, if your full controller class is App\Http\Controllers\Photos\AdminController
, you would register a route like so:
Route::get('foo', 'Photos\AdminController@method');
コントローラールートへの名前付けNaming Controller Routes
クロージャールートと同様に、コントローラールートにも名前が指定できます。Like Closure routes, you may specify names on controller routes:
Route::get('foo', ['uses' => 'FooController@method', 'as' => 'name']);
コントローラーアクションへのURLURLs To Controller Actions
コントローラーアクションへのURLを生成するときは、action
ヘルパメソッドを使用します。To generate a URL to a controller action, use the action
helper method:
$url = action('App\Http\Controllers\FooController@method');
コントローラーの名前空間からの相対クラス名の一部だけを使用し、コントローラーアクションへのURLを生成したい場合は、URLジェネレーターへルート名前空間を登録してください。If you wish to generate a URL to a controller action while using only the portion of the class name relative to your controller namespace, register the root controller namespace with the URL generator:
URL::setRootControllerNamespace('App\Http\Controllers');
$url = action('FooController@method');
実行中のコントローラーアクション名を取得するには、currentRouteAction
メソッドが使えます。You may access the name of the controller action being run using the currentRouteAction
method:
$action = Route::currentRouteAction();
コントローラーミドルウェアController Middleware
ミドルウェアは、コントローラーアクションに対して、次のように指定します。Middleware[/docs/master/middleware] may be specified on controller routes like so:
Route::get('profile', [
'middleware' => 'auth',
'uses' => 'UserController@showProfile'
]);
また、コントローラーのコンストラクターでも、ミドルウェアを指定できます。Additionally, you may specify middleware within your controller's constructor:
class UserController extends Controller {
/**
* 新しいUserControllerのインスタンスの生成
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('log', ['only' => ['fooAction', 'barAction']]);
$this->middleware('subscribed', ['except' => ['fooAction', 'barAction']]);
}
}
暗黙のコントローラーImplicit Controllers
Laravelでは、一つのルートだけで、簡単にコントローラーの全アクションを定義できます。最初に、Route::controller
メソッドで、そのルートを定義します。Laravel allows you to easily define a single route to handle every action in a controller. First, define the route using the Route::controller
method:
Route::controller('users', 'UserController');
controller
メソッドは2つの引数を取ります。最初はコントローラーが処理するURIで、2つ目はコントローラーのクラス名です。次に、対応するHTTP動詞をプリフィックスにし、メソッドをコントローラーに追加してください。The controller
method accepts two arguments. The first is the base URI the controller handles, while the second is the class name of the controller. Next, just add methods to your controller, prefixed with the HTTP verb they respond to:
class UserController extends BaseController {
public function getIndex()
{
//
}
public function postProfile()
{
//
}
public function anyLogin()
{
//
}
}
index
メソッドは、コントローラーのルートURIに対応します。この場合、users
です。The index
methods will respond to the root URI handled by the controller, which, in this case, is users
.
コントローラーアクションに複数の単語を含める場合は、URIに「ダッシュ」記法を使用し、そのアクションへアクセスできます。例えば、コントローラーアクションがUserController
であれば、users/admin-profile
のURIにレスポンスします。If your controller action contains multiple words, you may access the action using "dash" syntax in the URI. For example, the following controller action on our UserController
would respond to the users/admin-profile
URI:
public function getAdminProfile() {}
RESTフルリソースコントローラーRESTful Resource Controllers
リソースフルコントローラーはリソースに関するRESTフルコントローラーを苦労をせずに構築してくれます。例えば、アプリケーションで保存されている「写真(phots)」関係のHTTPリクエストを処理するコントローラーを作成するとしましょう。Artisanコマンドラインでmake:controller
Artisanコマンドを使えば、そのようなコントローラを素早く生成できます。Resource controllers make it painless to build RESTful controllers around resources. For example, you may wish to create a controller that handles HTTP requests regarding "photos" stored by your application. Using the make:controller
Artisan command, we can quickly create such a controller:
php artisan make:controller PhotoController
次に、コントローラーへのリソースフルルートを登録します。Next, we register a resourceful route to the controller:
Route::resource('photo', 'PhotoController');
写真リソースの様々なRESTフルアクションを処理する多くのルートが、この1行のルート定義で作り出されます。同時に、生成されたコントローラーには、どのURI/動詞を処理するのかという情報を含んだスタブメソッドが、それぞれのアクションに対して用意されています。This single route declaration creates multiple routes to handle a variety of RESTful actions on the photo resource. Likewise, the generated controller will already have methods stubbed for each of these actions, including notes informing you which URIs and verbs they handle.
リソースフルコントローラーにより処理されるアクションActions Handled By Resource Controller
変数Verb | パスPath | アクションAction | ルート名Route Name |
---|---|---|---|
GETGET | /リソース名/resource | indexindex | resource.indexresource.index |
GETGET | /リソース名/create/resource/create | createcreate | resource.createresource.create |
POSTPOST | /リソース名/resource | storestore | resource.storeresource.store |
GETGET | /リソース名/{resource}/resource/{resource} | showshow | resource.showresource.show |
GETGET | /リソース名/{resource}/edit/resource/{resource}/edit | editedit | resource.editresource.edit |
PUT/PATCHPUT/PATCH | /リソース名/{resource}/resource/{resource} | updateupdate | resource.updateresource.update |
DELETEDELETE | /リソース名/{resource}/resource/{resource} | destroydestroy | resource.destroyresource.destroy |
リソースルートのカスタマイズCustomizing Resource Routes
さらに、リソースアクションの一部のみを取り扱うことも可能です。Additionally, you may specify only a subset of actions to handle on the route:
Route::resource('photo', 'PhotoController',
['only' => ['index', 'show']]);
Route::resource('photo', 'PhotoController',
['except' => ['create', 'store', 'update', 'destroy']]);
デフォルトで、すべてのリソースコントローラーアクションはルート名を持ちます。しかしオプションにnames
配列を渡すことで、こうした名前をオーバーライドすることもできます。By default, all resource controller actions have a route name; however, you can override these names by passing a names
array with your options:
Route::resource('photo', 'PhotoController',
['names' => ['create' => 'photo.build']]);
ネストしたリソースコントローラーの処理Handling Nested Resource Controllers
「ネスト」したリソースコントローラーには、ルート宣言で「ドット」記法を使用してください。To "nest" resource controllers, use "dot" notation in your route declaration:
Route::resource('photos.comments', 'PhotoCommentController');
これにより、「ネスト」したリソースが登録され、photos/{photos}/comments/{comments}
のURLにアクセスできるようになります。This route will register a "nested" resource that may be accessed with URLs like the following: photos/{photos}/comments/{comments}
.
class PhotoCommentController extends Controller {
/**
* 特定の写真のコメントを表示する
*
* @param int $photoId
* @param int $commentId
* @return Response
*/
public function show($photoId, $commentId)
{
//
}
}
リソースコントローラーへのルート追加Adding Additional Routes To Resource Controllers
デフォルトのリソースルート以外のルートをリソースコントローラーへ追加する必要がある場合は、Route::resource
の呼び出しより前に定義する必要があります。If it becomes necessary to add additional routes to a resource controller beyond the default resource routes, you should define those routes before your call to Route::resource
:
Route::get('photos/popular');
Route::resource('photos', 'PhotoController');
依存注入とコントローラーDependency Injection & Controllers
コンストラクターによる注入Constructor Injection
Laravelのサービスコンテナは、全コントローラーの依存解決のために使用されています。これにより、コントローラーが必要な依存をコンストラクターにタイプヒントで指定できるのです。The Laravel service container[/docs/master/container] is used to resolve all Laravel controllers. As a result, you are able to type-hint any dependencies your controller may need in its constructor:
<?php namespace App\Http\Controllers;
use Illuminate\Routing\Controller;
use App\Repositories\UserRepository;
class UserController extends Controller {
/**
* ユーザーリポジトリーインスタンス
*/
protected $users;
/**
* 新しいコントローラーインスタンスの生成
*
* @param UserRepository $users
* @return void
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}
}
もちろん、Laravelの契約もタイプヒントに指定できます。コンテナが依存解決できるものは、タイプヒントで指定できます。Of course, you may also type-hint any Laravel contract[/docs/master/contracts]. If the container can resolve it, you can type-hint it.
メソッドによる注入Method Injection
コンストラクターによる注入に加え、コントローラーのメソッドにタイプヒントで依存を指定することもできます。例えば、あるメソッドでRequest
インスタンスをタイプヒントで指定してみましょう。In addition to constructor injection, you may also type-hint dependencies on your controller's methods. For example, let's type-hint the Request
instance on one of our methods:
<?php namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class UserController extends Controller {
/**
* 新しいユーザーの保存
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
$name = $request->input('name');
//
}
}
もしコントローラーメソッドで、ルートパラメーターの入力が求められているのでしたら、依存定義の後に続けて、ルート引数を指定するだけです。If your controller method is also expecting input from a route parameter, simply list your route arguments after your other dependencies:
<?php namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
class UserController extends Controller {
/**
* 新しいユーザーの保存
*
* @param Request $request
* @param int $id
* @return Response
*/
public function update(Request $request, $id)
{
//
}
}
注目: メソッドによる注入はモデルの結合でも同様に動作します。コンテナは結合されたモデルの引数と、注入すべきモデルを聡明に判断します。Note: Method injection is fully compatible with model binding[/docs/master/routing#route-model-binding]. The container will intelligently determine which arguments are model bound and which arguments should be injected.
ルートキャッシュRoute Caching
アプリケーションがコントローラールートだけを使用していれば、Laravelのルートキャッシュを利用できる利点があります。ルートキャッシュを使用すれば、アプリケーションの全ルートを登録するのに必要な時間を劇的に減らすことができます。ある場合には、ルート登録が100倍も早くなります!ルートキャッシュを登録するには、route:catch
Arisanコマンドを実行するだけです。If your application is exclusively using controller routes, you may take advantage of Laravel's route cache. Using the route cache will drastically decrease the amount of time it take to register all of your application's routes. In some cases, your route registration may even be up to 100x faster! To generate a route cache, just execute the route:cache
Artisan command:
php artisan route:cache
これだけです!キャッシュされたルートファイルは、app/Http/routes.php
ファイルの代わりに使用されるようになります。その代わりに、新しいルートを追加するには、キャッシュルートを再構築する必要があります。ですから、プロジェクトの開発期間の最後に、一度だけroute:cache
を実行するほうが良いでしょう。That's all there is to it! Your cached routes file will now be used instead of your app/Http/routes.php
file. Remember, if you add any new routes you will need to generate a fresh route cache. Because of this, you may wish to only run the route:cache
command during your project's deployment.
新しいキャッシュルートのファイルを生成せず削除するためには、route:clear
コマンドを使います。To remove the cached routes file without generating a new cache, use the route:clear
command:
php artisan route:clear