基本的なルーティング

アプリケーションのほとんどのルートは、app/Http/routes.phpファイルの中で定義されるでしょう。このファイルは、App\Providers\RouteServiceProviderクラスによりロードされています。一番基本的な、LaravelのルートはURIと「クロージャー」を指定します。

基本のGETルート

Route::get('/', function()
{
    return 'Hello World';
});

他の基本ルート

Route::post('foo/bar', function()
{
    return 'Hello World';
});

Route::put('foo/bar', function()
{
    //
});

Route::delete('foo/bar', function()
{
    //
});

複数のHTTP動詞に対応するルートの登録

Route::match(['get', 'post'], '/', function()
{
    return 'Hello World';
});

全てのHTTP動詞に対応するルートの登録

Route::any('foo', function()
{
    return 'Hello World';
});

ルートに対するURLを生成する必要が時々起こると思います。urlヘルパーを使用できます。

$url = url('foo');

CSRFからの保護

Laravelでは、クロス・サイト・リクエスト・フォージェリからアプリケーションを簡単に守れます。クロス・サイト・リクエスト・フォージェリは悪意のあるエクスプロイトの一種であり、信頼するユーザーの代わりに、認められていないコマンドを実行します。

Laravelは、アプリケーションにより管理されているアクティブなユーザーの各セッションごとに、CSRF「トークン」を自動的に生成しています。このトークンは認証済みのユーザーが、実装にアプリケーションに対してリクエストを送信しているのかを確認するために役立ちます。

CSRFトークンのフォームへの挿入

<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">

もちろん、Bladeテンプレートエンジンを使用できます。

<input type="hidden" name="_token" value="{{ csrf_token() }}">

POST、PUT、DELETEリクエストのCSRFトークンを自分で確認する必要はありません。VerifyCsrfToken HTTPミドルウェアが、リクエスト中のトークンとセッションに保存されているトークンが一致するか、確認しています。

X-CSRF-TOKEN

さらに、"POST"パラメーターとしてCSRFトークンを見つけるため、このミドルウェアはJavaScriptのフレームワークで一般的に使用されている、X-XSRF-TOKENリクエストヘッダーもチェックします。例えば、"meta"タグの中にこのトークンを設置できます。送信前にjQueryを利用しヘッダーに付け加えてみましょう。

<meta name="csrf-token" content="{{ csrf_token() }}" />

$.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });

これで、全AJAXリクエストは自動的にCSRFトークンを含むようになります。

$.ajax({
   url: "/foo/bar",
})

X-XSRF-TOKEN

Laravelはさらに、XSRF-TOKENクッキーの中にCSRFトークンを保存します。このクッキーの値をX-XSRF-TOKENリクエストヘッダーに設定するために利用できます。AngularのようないくつかのJavaScriptフレームワークでは、自動的に行われます。

メモ:X-CSRF-TOKENX-XSRF-TOKENの違いは、前者が平文の値に使用されるのに対し、後者は暗号化された値で使用します。Laravelではクッキーは常に暗号化されるため、後者を使用しています。トークンの値を与えるためにcsrf_token()関数を使っている場合は、X-CSRF-TOKENヘッダーを使用する必要が多分あるでしょう。

擬似メソッド

HTMLフォームはPUTPATCHDELETEアクションをサポートしていません。ですから、PUTPATCHDELETEのルートを呼び出すHTMLフォームを定義している場合、_method隠しフィールドをそのフォームに追加する必要があります。

_methodフィールドで送る値は、HTTPリクエストのメソッドとして使用されます。例をご覧ください。

<form action="/foo/bar" method="POST">
    <input type="hidden" name="_method" value="PUT">
    <input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
</form>

ルートパラメーター

もちろんルート中にある、リクエストURIのセグメントを取得することもできます。

基本的なルートパラメーター

Route::get('user/{id}', function($id)
{
    return 'User '.$id;
});

注意: ルートパラメーターに-を含めることはできません。代わりに下線(_)を使ってください。

オプションのルートパラメーター

Route::get('user/{name?}', function($name = null)
{
    return $name;
});

デフォルト値を指定したオプションのルートパラメーター

Route::get('user/{name?}', function($name = 'John')
{
    return $name;
});

正規表現によるルートの束縛

Route::get('user/{name}', function($name)
{
    //
})
->where('name', '[A-Za-z]+');

Route::get('user/{id}', function($id)
{
    //
})
->where('id', '[0-9]+');

正規表現の配列による束縛

Route::get('user/{id}/{name}', function($id, $name)
{
    //
})
->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

グローバルパターンの定義

patternメソッドを使用すれば、ルートパラメーターを指定した正規表現で常に束縛することができます。これらは、RouteServiceProviderbootメソッドで定義することを推奨します。

$router->pattern('id', '[0-9]+');

パターンが定義されると、そのパラメーターを使用する全ルートに適用されます。

Route::get('user/{id}', function($id)
{
    // Only called if {id} is numeric.
});

ルートパラメーター値へのアクセス

ルートの外で、ルートパラメーターの値にアクセスする必要がある場合、inputメソッドが使用できます。

if ($route->input('id') == 1)
{
    //
}

また、現在のルートパラメーターへは、Illuminate\Http\Requestインスタンスによってもアクセスできます。現在のリクエストのリクエストインスタンスは、Requestファサードや、依存が注入される場所でIlluminate\Http\Requestをタイプヒントで指定することによってもアクセス可能です。

use Illuminate\Http\Request;

Route::get('user/{id}', function(Request $request, $id)
{
    if ($request->route('id'))
    {
        //
    }
});

名前付きルート

リダイレクトやURLを生成する場合により便利にするために、ルートにつけた名前によりルートを参照することができます。ルート名を配列キーのasで定義してください。

Route::get('user/profile', ['as' => 'profile', function()
{
    //
}]);

コントローラアクションに対してもルート名を指定できます。

Route::get('user/profile', [
    'as' => 'profile', 'uses' => 'UserController@showProfile'
]);

これで、ルート名をURLやリダイレクトを生成する場合に使用できます。

$url = route('profile');

$redirect = redirect()->route('profile');

実行中のルート名はcurrentRouteNameメソッドでアクセスできます。

$name = Route::currentRouteName();

ルートグループ

URLセグメント、ミドルウェア、名前空間など、多くのルートで同じ共通の制約・設定を行いたい場合があります。全てのルートにこうしたオプションを個別に指定する代わりに、まとめてルートへ属性を適用できるルートグループが使用できます。

共通の属性は、Route::groupメソッドの最初の引数として配列で指定します。

ミドルウェア

グループの全ルートへミドルウェアを適用するには、属性配列の中のmiddleware引数を指定し、ミドルウェアのリストを定義してください。この配列に指定された順番で、ミドルウェアが実行されます。

Route::group(['middleware' => ['foo', 'bar']], function()
{
    Route::get('/', function()
    {
        // FooとBarミドルウェア適用
    });

    Route::get('user/profile', function()
    {
        // FooとBarミドルウェア適用
    });

});

名前空間

グループ中の全コントローラーへ名前空間を指定するには、グループ属性配列中にnamespace引数を使用します。

Route::group(['namespace' => 'Admin'], function()
{
    // "App\Http\Controllers\Admin"名前空間のコントローラー

    Route::group(['namespace' => 'User'], function()
    {
        // "App\Http\Controllers\Admin\User"名前空間のコントローラー
    });
});

注意: デフォルトでRouteServiceProviderが名前空間グループを含むroutes.phpファイルを読み込んでいるので、完全な名前空間の先頭からApp\\Http\\Controllersを除いてコントローラールートを登録できます。

サブドメインルーティング

Laravelのルートではサブドメインをワイルドカードで処理でき、ドメイン名のワイルドカードパラメーターをルートに渡すことも可能です。

サブドメインルートの登録

Route::group(['domain' => '{account}.myapp.com'], function()
{

    Route::get('user/{id}', function($account, $id)
    {
        //
    });

});

ルートのプレフィックス

ルートグループのプレフィックスはグループの属性配列でprefixオプションを使用し指定します。

Route::group(['prefix' => 'admin'], function()
{
    Route::get('users', function()
    {
        // "/admin/users"のURLと一致
    });
});

さらに、ルートへ共通のパラメーターを渡すために、prefixパラメーターを利用することもできます。

ルートプレフィックス中でURLパラメーターの登録

Route::group(['prefix' => 'accounts/{account_id}'], function()
{
    Route::get('detail', function($account_id)
    {
        //
    });
});

プレフィックス中で名前をつけたパラメーターに対し、制約を指定することも可能です。

Route::group([
    'prefix' => 'accounts/{account_id}',
    'where' => ['account_id' => '[0-9]+'],
], function() {

    // ここでルートを定義する
});

ルートとモデルの結合

Laravelモデル結合は、モデルのインスタンスをルートから受け取る、便利な手法です。例えば、ユーザーのIDを受け取る代わりに、そのIDに合致するUserモデルのインスタンスを受け取ることができます。

最初に、ルーターのmodelメソッドで指定したパラメーターで使用するモデルを指定します。モデルの結合は、RouteServiceProvider::bootメソッドの中で定義してください。

モデルとパラメーターを結合する

public function boot(Router $router)
{
    parent::boot($router);

    $router->model('user', 'App\User');
}

次に、{user}パラメーターを含んだルートを定義します。

Route::get('profile/{user}', function(App\User $user)
{
    //
});

{user}パラメーターとUserモデルを結合済みですから、ルートからUserインスタンスが渡されます。例えば、profile/1がリクエストされると、IDが1のUserインスタンスが渡されます。

注目:もしデータベースにモデルのインスタンスが見つからない場合、404エラーがスローされます

もし独自の"not found"動作を指定したい場合は、modelメソッドへクロージャーを3つ目の引数として渡してください。

Route::model('user', 'User', function()
{
    throw new NotFoundHttpException;
});

独自のインスタンス取得ロジックを実装したい場合は、Route::bindメソッドを使用してください。bindメソッドのクロージャーには、URIセグメントの値が渡されますので、ルートへ注入したいクラスのインスタンスを返してください。

Route::bind('user', function($value)
{
    return User::where('name', $value)->first();
});

404エラーのthrow

手動で404エラーをルートから発生させるには2つの手法があります。最初の方法はabortヘルパーを使用するものです。

abort(404);

abortヘルパーはただ、Symfony\Component\HttpKernel\Exception\HttpException例外を指定したステータスコードと共に投げる(throw)だけです。

2つめの方法はSymfony\Component\HttpKernel\Exception\NotFoundHttpExceptionのインスタンスを投げる方法です。

404例外の取り扱いやエラーのカスタム処理を行う詳しい方法は、ドキュメントのエラーの章をご覧ください。