> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# コントローラー

> Laravelのコントローラーの作成方法とルーティングとの連携を解説します。

## コントローラーとは

ルートファイルにすべてのリクエスト処理ロジックをクロージャとして定義する代わりに、「コントローラー」クラスを使ってこの動作を整理できます。
コントローラーは関連するリクエスト処理ロジックを1つのクラスにまとめられます。

例えば `UserController` クラスは、ユーザーの表示・作成・更新・削除など、ユーザーに関するすべての受信リクエストを処理できます。
デフォルトでは、コントローラーは `app/Http/Controllers` ディレクトリに格納されます。

## コントローラーの作成

新しいコントローラーを素早く生成するには、`make:controller` Artisanコマンドを使います。
アプリケーションのすべてのコントローラーは、デフォルトで `app/Http/Controllers` ディレクトリに格納されます。

```shell theme={null}
php artisan make:controller UserController
```

## 基本的なコントローラー

コントローラークラスは、受信するHTTPリクエストに応答するいくつかのpublicメソッドを持てます。

```php theme={null}
<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\View\View;

class UserController extends Controller
{
    /**
     * 指定されたユーザーのプロフィールを表示する
     */
    public function show(string $id): View
    {
        return view('user.profile', [
            'user' => User::findOrFail($id)
        ]);
    }
}
```

コントローラークラスとメソッドを作成したら、次のようにコントローラーメソッドへのルートを定義できます。

```php theme={null}
use App\Http\Controllers\UserController;

Route::get('/user/{id}', [UserController::class, 'show']);
```

受信リクエストが指定されたルートURIに一致すると、`App\Http\Controllers\UserController` クラスの `show` メソッドが呼び出され、ルートパラメータがメソッドに渡されます。

<Info>
  コントローラーはベースクラスを継承する必要はありません。ただし、すべてのコントローラーで共有すべきメソッドを持つベースコントローラークラスを継承すると便利な場合があります。
</Info>

## シングルアクションコントローラー

コントローラーのアクションが特に複雑な場合、コントローラークラス全体をその単一のアクションに専念させると便利です。
これを実現するには、コントローラー内に単一の `__invoke` メソッドを定義します。

```php theme={null}
<?php

namespace App\Http\Controllers;

class ProvisionServer extends Controller
{
    /**
     * 新しいWebサーバーをプロビジョニングする
     */
    public function __invoke()
    {
        // ...
    }
}
```

シングルアクションコントローラーのルートを登録する場合、コントローラーメソッドを指定する必要はありません。
コントローラー名だけをルーターに渡します。

```php theme={null}
use App\Http\Controllers\ProvisionServer;

Route::post('/server', ProvisionServer::class);
```

`make:controller` Artisanコマンドの `--invokable` オプションを使って、呼び出し可能なコントローラーを生成できます。

```shell theme={null}
php artisan make:controller ProvisionServer --invokable
```

## リソースコントローラー

アプリケーション内の各Eloquentモデルを「リソース」と考えると、各リソースに対して同じ操作セット（CRUD）を実行するのが一般的です。
Laravelのリソースルーティングは、典型的な作成・読み取り・更新・削除（CRUD）ルートを、1行のコードでコントローラーに割り当てます。

`make:controller` Artisanコマンドの `--resource` オプションを使って、これらのアクションを処理するコントローラーを素早く作成できます。

```shell theme={null}
php artisan make:controller PhotoController --resource
```

このコマンドは `app/Http/Controllers/PhotoController.php` にコントローラーを生成します。
コントローラーには利用可能な各リソース操作のメソッドがスタブとして含まれます。
次に、コントローラーを指すリソースルートを登録します。

```php theme={null}
use App\Http\Controllers\PhotoController;

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

この1行のルート宣言で、リソースへのさまざまなアクションを処理する複数のルートが作成されます。
生成されたコントローラーには、これらの各アクションのメソッドがすでにスタブとして含まれています。

| HTTPメソッド  | URI                    | アクション   | ルート名           |
| --------- | ---------------------- | ------- | -------------- |
| GET       | `/photos`              | index   | photos.index   |
| GET       | `/photos/create`       | create  | photos.create  |
| POST      | `/photos`              | store   | photos.store   |
| GET       | `/photos/{photo}`      | show    | photos.show    |
| GET       | `/photos/{photo}/edit` | edit    | photos.edit    |
| PUT/PATCH | `/photos/{photo}`      | update  | photos.update  |
| DELETE    | `/photos/{photo}`      | destroy | photos.destroy |

<Info>
  `php artisan route:list` コマンドを実行すると、アプリケーションのルートの概要を素早く確認できます。
</Info>

### 部分的なリソースルート

リソースルートを宣言する際に、コントローラーが処理すべきアクションのサブセットを指定できます。

```php theme={null}
use App\Http\Controllers\PhotoController;

Route::resource('photos', PhotoController::class)->only([
    'index', 'show'
]);

Route::resource('photos', PhotoController::class)->except([
    'create', 'store', 'update', 'destroy'
]);
```

### APIリソースルート

APIで使用するリソースルートを宣言する場合、`create` や `edit` などHTMLテンプレートを表示するルートを除外したいことがよくあります。
`apiResource` メソッドを使うと、これら2つのルートを自動的に除外できます。

```php theme={null}
use App\Http\Controllers\PhotoController;

Route::apiResource('photos', PhotoController::class);
```

## 依存性の注入

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

LaravelのサービスコンテナはすべてのLaravelコントローラーの依存解決に使われます。
そのため、コントローラーのコンストラクターにコントローラーが必要とする依存をタイプヒントで指定できます。
宣言された依存は自動的に解決され、コントローラーインスタンスに注入されます。

```php theme={null}
<?php

namespace App\Http\Controllers;

use App\Repositories\UserRepository;

class UserController extends Controller
{
    /**
     * 新しいコントローラーインスタンスの生成
     */
    public function __construct(
        protected UserRepository $users,
    ) {}
}
```

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

コンストラクターインジェクションに加えて、コントローラーのメソッドの依存もタイプヒントで指定できます。
メソッドインジェクションの一般的なユースケースは、`Illuminate\Http\Request` インスタンスをコントローラーメソッドに注入することです。

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * 新しいユーザーを保存する
     */
    public function store(Request $request): RedirectResponse
    {
        $name = $request->name;

        // ユーザーを保存する処理...

        return redirect('/users');
    }
}
```

コントローラーメソッドがルートパラメータからの入力も受け取る場合は、他の依存の後にルート引数をリストします。
例えば、ルートが次のように定義されている場合を考えます。

```php theme={null}
use App\Http\Controllers\UserController;

Route::put('/user/{id}', [UserController::class, 'update']);
```

次のようにコントローラーメソッドを定義することで、`Illuminate\Http\Request` をタイプヒントしながら `id` パラメータにもアクセスできます。

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * 指定されたユーザーを更新する
     */
    public function update(Request $request, string $id): RedirectResponse
    {
        // ユーザーを更新する処理...

        return redirect('/users');
    }
}
```

<Tip>
  依存性の注入を活用することで、テスト時にモックを差し込みやすくなり、コードのテスタビリティが向上します。
</Tip>

## 次のステップ

<Card title="ルーティング" icon="route" href="/jp/routing">
  ルートの定義方法やコントローラーとの連携を振り返ります。
</Card>
