Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Undocumented Laravel (2) Controller 編

More than 3 years have passed since last update.

この記事について

下記の記事の続編です。
Undocumented Laravel (1) Routing 編 - Qiita

Laravel 公式サイトに載ってない機能について紹介します。
に載ってない機能について紹介します。
今回は、コントローラー編です。
公式ドキュメントに載ってないということは、後方互換を考慮せずに変更されることもありうるので、使用にあたっては熟慮されることをオススメします。
役に立つか立たないか、ご自身の目でお確かめください。
環境

  • PHP 7.1.4
  • Laravel 5.5.25

目次

  1. 基底クラスを継承しない Controller の振る舞い
  2. callAction で共通処理

1. 基底クラスを継承しない Controller の振る舞い

下記の記事の補足のようなかんじになってしまいますが、もう少し深掘りしてみます。

参考)LaravelのControllerクラスって何やってるの? - Qiita

下記の部分です。

image.png

ここで言う「基底クラス」は、app/Http/Controllers/Controller.php で定義されているクラスのことです。
中身はシンプルで、

extends Illuminate\Routing\Controller

して、

use AuthorizesRequests, DispatchesJobs, ValidatesRequests;

しているだけです。

基底クラスを継承しない Controller をつくったとき、どうやって代替するか、下記に示します。

1. Controller を継承しないとどうなるか

$this->middleware() が使えなくなります。

代替案

ルーティング定義のところで定義しましょう。

例えば HomeController で、

$this->middleware('auth');

のように定義していたら、

Route::get('/home', 'HomeController@index')->middleware('auth');

のようにします。

2. AuthorizesRequests が使えなくなるとどうなるか

$this->authorize() が使えなくなります。

代替案

Gate::authorize() を使いましょう。

$this->authorize('update-post');

と書いていた部分は、

Gate::authorize('update-post');

とすれば同等になります。

3. DispatchesJobs

$this->dispatch() が使えなくなります。

代替案

Job 自体にディスパッチさせるか、dispatch() ヘルパーを使いましょう。

これは単純で、

$this->dispatch(new SomeJob());

となっているところを、

SomeJob::dispatch();

とするか、

dispatch(new SomeJob());

とすればOKです。

4. ValidatesRequests

$this->vaildate() が使えなくなります。

代替案

FormRequest クラスを使いましょう。

まぁ、Controller にバリデーション書くと Fat Controller 警察のひとたちに怒られますので、継承するしないにかかわらず、FormRequest でやっておくのが無難です。

SomeController.php
$this->validate($request, [
    'title' => 'required|unique:posts|max:255',
    'body' => 'required',
]);

とかやっている箇所があったら、

SomeRequest.php
public function rules()
{
    return [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ];
}

に移しましょう。

2. callAction で共通処理

おまけです。

Illuminate\Routing\Controller クラスに、 callAction というメソッドがあって、なんだこれと思ったので、使い途を考えてみました。

Illuminate\Routing\ControllerDispatcher クラスで以下のように呼ばれています。

ControllerDispatcher.php
    public function dispatch(Route $route, $controller, $method)
    {
        $parameters = $this->resolveClassMethodDependencies(
            $route->parametersWithoutNulls(), $controller, $method
        );

        if (method_exists($controller, 'callAction')) {
            return $controller->callAction($method, $parameters);
        }

        return $controller->{$method}(...array_values($parameters));
    }

シグネチャは下記です。

Response function callAction(string $method, array $parameters)

アクションメソッドで DI してると、上の $parameters には、インスタンス化されて入ってくるので、これらを使って何かする処理が書けそうです。

SomeController.php
class SomeController extends Controller
{
    public function callAction(string $method, array $parameters)
    {
         $someService = $parameters[0];
         $someModel = $parameters[1];
         //
         return parent::callAction($method, [$someService, $someModel]);
    }

    public function index(SomeService $service, SomeModel $model)
    {
        //
    }
}

最後に親の callAction() を呼べばOKです。

まとめ

至れり尽くせりな印象の Laravel ですが、フレームワークが提供する Controller の機能は驚くほど少なかったです(最初は Controller 編をスキップしようかと思ったくらい)。

他にも公式ドキュメントに載っていないコントローラー周りの便利な機能があれば、ぜひ、コメント欄にてご紹介ください :bow:

nunulk
PHP, Laravel, オブジェクト指向プログラミング, デザインパターン, リファクタリング, 関数プログラミング, etc.
http://nunulk.hatenablog.com
phper-oop
ペチオブはオブジェクト指向ワーキンググループです。様々なエンジニアの方に参加頂いております。
https://phper-oop.connpass.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away