Laravel 5.2 HTTPコントローラー

イントロダクション

全リクエストの処理をたった一つのroutes.phpファイルで定義するよりも、コントローラークラスにより組織立てたいと、皆さんも考えるでしょう。関連のあるHTTPリクエストの処理ロジックを一つのクラスへまとめ、グループ分けができます。コントローラーはapp/Http/Controllersディレクトリ下に設置します。

基本のコントローラー

これは基本的なコントローラーの一例です。全てのLaravelコントローラーはLaravelにデフォルトで含まれている基本コントローラークラスを拡張します。

<?php

namespace App\Http\Controllers;

use App\User;
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)]);
    }
}

コントローラーアクションへルート付けるには、次のようにします。

Route::get('user/{id}', 'UserController@showProfile');

これで指定したルートのURIにリクエストが一致すれば、UserControllershowProfileメソッドが実行されます。もちろん、ルートパラメーターはメソッドに渡されます。

コントローラーと名前空間

とても重要な注目ポイントは、コントローラーの完全な名前空間を指定する必要がないことです。「先頭」のApp\Http\Controllers名前空間に続くクラス名の部分だけを指定しています。RouteServiceProviderがコントローラーの名前空間を指定したルートグループの中で、routes.phpファイルをロードします。

App\Http\Controllersディレクトリより深く、コントローラのPHP名前空間をネストしたり、組織立てたりする場合でも、単に先頭のApp\Http\Controllers名前空間からの相対クラス名を指定するだけです。ですから、コントローラーの完全なクラス名がApp\Http\Controllers\Photos\AdminControllerならば、次のようにルートを登録します。

Route::get('foo', 'Photos\AdminController@method');

コントローラールートの命名

クロージャルートと同様に、コントローラールートにも名前が指定できます。

Route::get('foo', ['uses' => 'FooController@method', 'as' => 'name']);

名前付きルートに対するURLを生成するにはrouteヘルパが使用できます。

$url = route('name');

コントローラーミドルウェア

ミドルウェアは、コントローラーアクションに対して、次のように指定します。

Route::get('profile', [
    'middleware' => 'auth',
    'uses' => 'UserController@showProfile'
]);

またはコントローラーのコンストラクターでも、ミドルウェアを指定できます。middlewareメソッドを使いコントローラーに対しミドルウェアを簡単に指定できます。特定のメソッドに対してだけミドルウェアを指定することも可能です。

class UserController extends Controller
{
    /**
     * 新しいUserControllerインスタンスの生成
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');

        $this->middleware('log', ['only' => [
            'fooAction',
            'barAction',
        ]]);

        $this->middleware('subscribed', ['except' => [
            'fooAction',
            'barAction',
        ]]);
    }
}

RESTフルリソースコントローラー

リソースフルコントローラーにより、リソースに関するRESTフルコントローラーを苦労せずに構築できます。例えば、アプリケーションで保存されている「写真(phots)」関係のHTTPリクエストを処理するコントローラーを作成するとしましょう。Artisanコマンドラインでmake:controller Artisanコマンドを使えば、対応するコントローラをあっという間に生成できます。

php artisan make:controller PhotoController --resource

このArtisanコマンドはapp/Http/Controllers/PhotoController.phpとしてコントローラーファイルを生成します。コントローラーは使用可能な各リソース操作に対するメソッドを含んでいます。

次に、コントローラーへのリソースフルルートを登録します。

Route::resource('photo', 'PhotoController');

写真リソースの様々なRESTフルアクションを処理する多くのルートが、この1行のルート定義で作り出されます。同時に、生成されたコントローラーには、どのURI/動詞を処理するのかという情報を含んだスタブメソッドが、それぞれのアクションに対して用意されています。

リソースコントローラーにより処理されるアクション

動詞 パス アクション ルート名
GET /photo index photo.index
GET /photo/create create photo.create
POST /photo store photo.store
GET /photo/{photo} show photo.show
GET /photo/{photo}/edit edit photo.edit
PUT/PATCH /photo/{photo} update photo.update
DELETE /photo/{photo} destroy photo.destroy

HTTPフォームはPUT、PATCH、DELETEリクエストを送れないため、HTTP動詞を指定する_method隠しフィールドを付ける必要があります。

<input type="hidden" name="_method" value="PUT">

部分的なリソースルート

リソースルートの宣言時に、ルートで処理するアクションの一部を指定可能です。

Route::resource('photo', 'PhotoController', ['only' => [
    'index', 'show'
]]);

Route::resource('photo', 'PhotoController', ['except' => [
    'create', 'store', 'update', 'destroy'
]]);

リソースルートの命名

全てのリソースコントローラーアクションは、デフォルトのルート名が決められています。しかし、オプションにnames配列を渡せば、こうした名前をオーバーライドできます。

Route::resource('photo', 'PhotoController', ['names' => [
    'create' => 'photo.build'
]]);

リソースルートパラメータの命名

Route::resourceはデフォルトで、リソース名にもとづきリソースルートのルートパラメータを生成します。オプション配列でparametersを指定することで簡単に、このリソース毎の基本的な命名規約をオーバーライドできます。parameters配列は、リソース名とパラメータ名の連想配列で指定します。

Route::resource('user', 'AdminUserController', ['parameters' => [
    'user' => 'admin_user'
]]);

上記のサンプルコードは、リソースのshowルートで次のURIを生成します。

/user/{admin_user}

パラメータ名の配列を渡す代わりに、singularを指定すると、Laravelはデフォルトのパラメータ名の「単数形」を使用します。

Route::resource('users.photos', 'PhotoController', [
    'parameters' => 'singular'
]);

// /users/{user}/photos/{photo}

もしくは、リソースルートパラメータをグローバルに単数形にする、もしくは名前をグローバルにマッピングもできます。

Route::singularResourceParameters();

Route::resourceParameters([
    'user' => 'person', 'photo' => 'image'
]);

リソースパラメータをカスタマイズする場合、命名のプライオリティを認識しておくことが重要です。

  1. Route::resourceへ明示的に渡されたパラメータ
  2. Route::resourceParametersでグローバルに設定
  3. Route::resourceparameters配列にsingularを設定するか、Route::singularResourceParametersにより設定
  4. デフォルトの命名規則

リソースコントローラーへのルート追加

デフォルトのリソースルート以外のルートをリソースコントローラーへ追加する場合は、Route::resourceの呼び出しより前に定義する必要があります。そうしないと、resourceメソッドにより定義されるルートが、追加のルートより意図に反して優先されます。

Route::get('photos/popular', 'PhotoController@method');

Route::resource('photos', 'PhotoController');

依存注入とコントローラー

コンストラクターインジェクション

全コントローラーの依存を解決するために、Laravelのサービスコンテナが使用されます。これにより、コントローラーが必要な依存をコンストラクターにタイプヒントで指定できるのです。依存クラスは自動的に解決され、コントローラーへインスタンスが注入されます。

<?php

namespace App\Http\Controllers;

use App\Repositories\UserRepository;

class UserController extends Controller
{
    /**
     * ユーザリポジトリーインスタンス
     */
    protected $users;

    /**
     * 新しいコントローラーインスタンス
     *
     * @param  UserRepository  $users
     * @return void
     */
    public function __construct(UserRepository $users)
    {
        $this->users = $users;
    }
}

もちろん、Laravelの契約もタイプヒントに指定できます。コンテナが解決できるのであれば、タイプヒントで指定できます。

メソッドインジェクション

コンストラクターによる注入に加え、コントローラーのメソッドでもタイプヒントにより依存を指定することもできます。たとえば、あるメソッドでIlluminate\Http\Requestインスタンスをタイプヒントにより指定してみましょう。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * 新ユーザの保存
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $name = $request->input('name');

        //
    }
}

コントローラーメソッドへルートパラメーターによる入力値が渡される場合でも、依存定義の後に続けてルート引数を指定するだけです。たとえば以下のようにルートが定義されていれば:

Route::put('user/{id}', 'UserController@update');

下記のようにIlluminate\Http\Requestをタイプヒントで指定しつつ、コントローラーメソッドで定義しているidルートパラメータにアクセスできます。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * 指定ユーザの保存
     *
     * @param  Request  $request
     * @param  string  $id
     * @return Response
     */
    public function update(Request $request, $id)
    {
        //
    }
}

ルートキャッシュ

注意: ルートキャッシュはクロージャベースのルートには動作しません。ルートキャッシュを使用するには、全クロージャルートをコントローラークラスを使用するように変更する必要があります。

アプリケーションがコントローラーベースのルート定義だけを使用しているなら、Laravelのルートキャッシュを利用できる利点があります。ルートキャッシュを使用すれば、アプリケーションの全ルートを登録するのに必要な時間を劇的に減らすことができます。ある場合には、ルート登録が100倍も早くなります。ルートキャッシュを登録するには、route:cache Arisanコマンドを実行するだけです。

php artisan route:cache

これだけです。キャッシュされたルートファイルは、app/Http/routes.phpファイルの代わりに使用されるようになります。その代わりに、新しいルートの追加を反映するには、キャッシュしたルートを再構築する必要があります。ですからプロジェクトの開発期間の最後に、一度だけroute:cacheを実行するほうが良いでしょう。

キャッシュルートのファイルを削除するには、route:clearコマンドを使います。

php artisan route:clear

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる