【Laravel】コントローラーとは？作成や編集方法を実例で解説。

Laravelのコントローラーについて。実際にコントローラーを作成してブラウザに表示させることで理解を深める。

##目次

1. [コントローラーとは？](#コントローラーとは)
2. [コントローラーの作成方法](#コントローラーの作成方法)
3. [コントローラーの保存場所](#コントローラーの保存場所)
4. [コントローラーの中身](#コントローラーの中身)
5. [コントローラーの作成例](#コントローラーの作成例)
6. [コントローラー呼び出し時の注意点](#コントローラー指定時の注意点)
7. [コントローラーでviewファイルを呼び出す](#コントローラーでviewファイルを呼び出す)




<br>
##コントローラーとは？
Laravelのコントローラーでは、クラスを作成しメソッドを定義することができる。

ルーティングファイル（web.php）などにメソッドを記述していくとファイル長が膨大になってしまうため、コントローラーを使用することで、メソッドを利用しやすくなる。



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

・`$ php artisan make:controller コントローラー名`

コントローラー名は冒頭大文字のキャメル表記。

```:例
$ php artisan make:controller HelloController

Controller created successfully.
```


<br>
##コントローラーの保存場所
artisanコマンドを実行すると、app/Http/Controllers内に新たにファイルが生成される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/67276328-5a5b-0c79-559e-203566a5df19.png)

↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/5f014179-c20f-7ac3-ccaa-649aeee64171.png)


##専用のディレクトリの中に入れたい場合
コントローラー名の前にディレクトリ名を付ければOK。

例: `php artisan make:controller Test/HelloController`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/d3cd449e-bd37-64e1-e699-e7e960c3582b.png)



<br>
##コントローラーの中身

```php:
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HelloController extends Controller
{
    //
}
```

・`namespace App\Http\Controllers;`
名前空間。

app/Http/Controllers配下にファイルがあるため、そのまま名前空間として指定。

名前空間をつけることで、同じメソッド名でも名前空間が異なればそれぞれ別のメソッドとして使うことができる。


・`use 名前空間`
指定した名前空間をインポート。


・`use Illuminate\Http\Request;`
LaravelのAPIである、名前空間Illuminate\Http\Requestをインポートしている。
これで、Request.phpに定義されているメソッドが使えるようになる。


**▼Illuminate\Http\Requestの場所**
`vender > laravel > framework > src > Illuminate > Http > Request`

＞[Requestメソッド一覧](https://laravel.com/api/5.5/Illuminate/Http/Request.html)


<br>
・`class HelloController extends Controller`
定義したクラス名HelloControllerに、親クラスとして、**Controllerクラスを継承**している。

Controllerクラスには、`validate()`や`middleware()`など便利なメソッドが定義されている。



・`{ // }`
ここに、メソッドを記述していく。



<br>
##コントローラーの作成例
###step1. メソッドを定義
//の中に以下を追記

```php:
public function message(){
        $msg = 'こんにちは';
        return $msg;
    }
```

messageメソッドを呼び出すと、「こんにちは」を返す。


```php:HelloController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HelloController extends Controller
{
    public function message(){
        $msg = 'こんにちは';
        return $msg;
    }
}
```


<br>
###step2. ルーティングで呼び出す

```php:web.php
Route::get('msg', 'App\Http\Controllers\HelloController@message');
```

URIがmsgにアクセスしたら、HelloControllerのmessageメソッドを実行する。

以上で完了。


<br>
**▼ブラウザの表示**

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/92822a66-8a9a-e4c3-ee34-c56d8cae5056.png)|
|:--|



<br>
##コントローラー指定時の注意点
Laravel7までは、`App\Http\Controllers\`が省略できたが、Laravel8からは省略するとエラーが表示されるようになった。

対策として**完全な名前空間で指定**した。

他にも、Laravel7の環境と同じにする方法や、アクション構文を使用する方法がある。

<br>
###Laravel7と同じ環境にする
以下ファイルのコメントアウトを解除する。
`app > Providers > RouteServiceProvider.php`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/00d1dd3f-7b55-7635-f877-4b6927ca9a45.png)


```php:解除するコメントアウト
//protected $namespace = 'App\\Http\\Controllers';
```


```php:RouteServiceProvider.php
    protected $namespace = 'App\\Http\\Controllers';  //コメントアウトを解除

    /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @return void
     */
    public function boot()
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::prefix('api')
                ->middleware('api')
                ->namespace($this->namespace)
                ->group(base_path('routes/api.php'));

            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/web.php'));
        });
    }
```

<br>
ルーティングのコントローラー名を簡略化して完了。

```php:web.php
Route::get('msg', 'HelloController@message');
```



<br>
##アクション構文を使用する
ルーティングファイルの冒頭で、`use`を使ってHelloControllerクラスをインポートする。

・`use App\Http\Controllers\HelloController;`


getメソッドの第二引数で以下を指定。
・`[コントローラー名::class, 'メソッド名']`


```php:web.php
use Illuminate\Support\Facades\Route;  //デフォルトで記述
use App\Http\Controllers\HelloController; //追記

Route::get('msg', [HelloController::class, 'message']);
```



<br>
##コントローラーでviewファイルを呼び出す
コントローラーのメソッドが呼び出されると、viewファイルを描画するプログラムを作成する。

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

```php:HelloController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class HelloController extends Controller
{
    public function message(){
        $msg = 'こんにちは';
        $title = 'this is title!';

        return view('child', ['hello'=>$msg, 'title'=>$title]);
    }
}
```

HelloControllerのmessageメソッドを実行すると、child.blade.phpを表示する。

その際、`hello`という変数で`$msg`を、`title`という変数で`$title`を渡す。


<br>
##step2. viewファイルの作成
ここでは、child.blade.phpと、レイアウトとなるapp.blade.phpを作成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/b18ff0b7-cb08-a551-8a16-496c2c8e64ed.png)

```php:app.blade.php
<html>
    <head>
        <title>@yield('title')</title>
    </head>
    <body>
        <div class="container">
            @yield('content')
        </div>
    </body>
</html>
```

親ビューとなるapp.blade.phpを作成。
`@yield`で子ビューのセクションを呼び出している。


<br>

```php:child.blade.php
@extends('layouts.app')

@section('title', $title)

@section('content')
    <p>{{ $hello }}</p>
@stop
```

`@extends`で親ビューを継承。
`@section`でコントローラーから渡された変数を使用。


<br>
##step3. ルーティングの作成
パス「xxx」にアクセスすると、HelloControllerのmessageメソッドを実行するようにルーティングファイルに記述。

```php:web.php
Route::get('xxx', 'HelloController@message');
```

以上で完了。



>＞section, yield, extendの詳細は[こちら](https://qiita.com/yuta-38/items/3435e92c76ef0e823a8d)を参照


<br>
**▼ブラウザの表示**

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/ac4a4815-b5e9-10fc-4ecb-563298e66c04.png)|
|:--|

ページタイトルと、ページの内容に、コントローラーで定義した変数が表示されている。