Laravel 5.1 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

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

$url = route('name');

さらにactionヘルパメソッドを使い、コントローラークラスとメソッド名によるURLを生成できます。この場合もベースとなるApp\Http\Controllers名前空間に引き続くコントローラークラス名の部分のみ指定してください。

$url = action('FooController@method');

RouteファサードのcurrentRouteActionメソッドを実行すれば、コントローラーとアクション名にアクセスできます。

$action = Route::currentRouteAction();

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

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

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

この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

部分的なリソースルート

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

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('photos.comments', 'PhotoCommentController');

これにより「ネスト」したリソースが登録され、photos/{photos}/comments/{comments}のURLにアクセスできるようになります。

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;

class PhotoCommentController extends Controller
{
    /**
     * 特定の写真のコメント表示
     *
     * @param  int  $photoId
     * @param  int  $commentId
     * @return Response
     */
    public function show($photoId, $commentId)
    {
        //
    }
}

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

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

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

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

暗黙のコントローラー

Laravelでは一つのルート定義だけで、コントローラーの全アクションを簡単に定義できます。最初に、Route::controllerメソッドで、そのルートを定義します。controllerメソッドは2つの引数を取ります。最初はコントローラーが処理するベースのURIで、2つ目はコントローラーのクラス名です。

Route::controller('users', 'UserController');

次にコントローラーへメソッドを追加します。メソッド名はHTTP動詞で始まり、それ以降は先頭を大文字にしたURIのセグメントです。

<?php

namespace App\Http\Controllers;

class UserController extends Controller
{
    /**
     * GET /usersのリクエストに対応
     */
    public function getIndex()
    {
        //
    }

    /**
     * GET /users/show/1のリクエストに対応
     */
    public function getShow($id)
    {
        //
    }

    /**
     * GET /users/admin-profileのリクエストに対応
     */
    public function getAdminProfile()
    {
        //
    }

    /**
     * POST /users/profileのリクエストに対応
     */
    public function postProfile()
    {
        //
    }
}

上の例にあるように、indexメソッドはルートのURI、この場合はusersをコントローラーで処理するために用意します。

ルート名の指定

コントローラーのルートに名前を付ける場合は、controllerメソッドの第3引数に名前の配列を指定することができます。

Route::controller('users', 'UserController', [
    'getShow' => 'user.show',
]);

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

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

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

<?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の契約もタイプヒントに指定できます。コンテナが解決できるのであれば、タイプヒントで指定できます。

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

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

<?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');

        //
    }
}

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

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

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

<?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)
    {
        //
    }
}

ルートキャッシュ

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

アプリケーションがコントローラールートだけを使用していれば、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)へ移動

その他

?

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