【Laravel】ControllerからViewへの変数渡し方法と表示まで

こんにちは、最近Laravel楽しいなと思っているLaravel初心者エンジニアです。

今回は**ControllerからViewへ変数渡す方法とView上で、その変数を展開するところまで**まとめてきたいと思います。

## Viewであるbladeファイルに変数を渡す方法

方法としては以下の3つがあります。

①配列を使って渡す
②withメソッドを使う
③compact関数を使う

どれを使っても変数を送信することができますが、
**可読性の点からcompact関数が良いとのこと。**


### 前提の準備

まずは事前準備ということで、以下を用意します。

1.ルーティングの記述
2.viewを返すControllerファイル
3.bladeファイル


1.ルーティング
```php:web.php
// localhost:8000/view にアクセスしたらVariableControllerのtest関数を呼び出す
Route::get('/view', 'VariableController@test');
```

2.Controllerファイル
```php:VariableController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class VariableController extends Controller
{
    public function test(){
        // 連想変数を用意
        $users = array(
            'id' => 0,
            'name' => 'テストさん',
            'gender' => '男性', 
        );        
    }
}
```

3.bladeファイル（一旦中身は空）
以下のディレクトリに追加します。

resources/views/test/test.blade.php

準備ができたところで、Viewに変数を渡すコードを見ていきましょう！


### ①配列で渡す

```php:VariableController.php
// class名など省略
public function test(){
    // 連想配列を用意
    $test = array(
        'id' => 0,
        'name' => 'テストさん',
        'gender' => '男性', 
    );
    return view('test/test',  ['user' => $test]); // user変数として渡す
}
```



### ②withメソッドを使って渡す。

```php:VariableController.php
public function test(){
    // 連想配列を用意
    $test = array(
        'id' => 0,
        'name' => 'テストさん',
        'gender' => '男性', 
    );
    return view('test/test')->with('user', $test); // user変数としてbladeに送る
}
```

### ③compact関数

この後のblade出力の都合上、連想配列を$userに変更してます。


```php:VariableController.php
public function test(){
    // 連想配列を用意 $userに変更
    $user = array(
        'id' => 0,
        'name' => 'テストさん',
        'gender' => '男性', 
    );
    return view('test/test', compact('user')); // user変数をbladeに送る、$マークがいらない。
}
```


## bladeに表示してみる

### 配列の中身を表示

最初に空で作成したtest.blade.phpに以下の記述を行います。

**@foeachで渡ってきた$userをループさせています。**
配列の値は$dataに格納して、pタグの中に表示させます。

また、**表示させる際は{{ }}（マスタッシュ構文）を使います。**
その時、**Laravelではエスケープ処理**も行ってくれています。

```php:test/test.blade.php
  @foreach($user as $data)
    <p>{{ $data }}</p>
  @endforeach
```

localhost:8000/view にアクセスして画面を確認してみましょう！
**どのパターンでも以下のスクショのように表示できたかと思います！**


![スクリーンショット 2022-03-20 18.46.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769210/445d78aa-25f8-5d7f-65a7-3b1ece52afd8.png)


### 連想配列の個別に表示

**[ ]で配列のプロパティを指定すれば、配列の中身を個別に出力**することも可能です。

```php:test/test.blade.php
<p>IDは: {{ $user['id'] }}</p>
<p>名前は: {{ $user['name'] }}</p>
<p>性別は: {{ $user['gender'] }}</p>
```
表示は以下の様になります。

![スクリーンショット 2022-03-21 1.47.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769210/7967e8b9-3611-82e2-0fd1-83e7aa49982d.png)


### 中身を一覧表示したい際に躓いたエラー

bladeに表示を行う際に、foreachを使わず以下のように書いてみました。

```php:test/test.blade.php
<p>{{ $user }}</p> // 以下のエラーになる。
```

```
htmlspecialchars() expects parameter 1 to be string, array given 
```

簡単に説明すると、**{{}}(マスタッシュ構文)を使うとLaravelではエスケープ処理が行われますが、
その際の渡す値は文字列でなければなりません**と怒られています。

連想配列をそのまま表示させることはできないとのことですね。
普段のVue感覚でいけると思ってしまった。。（笑）


### 配列の中身をbladeで確認したい場合

では配列を一覧で確認したい場合はどうするかと言うと、phpの**ver_dump関数**を使います。

**blade内でphp関数を使う場合、@phpディレクティブが使えます！**

@phpから@endphpで囲った部分は、phpが使えるので以下の様に記述してみます。

```php:test/test.blade.php
@php 
  echo '<pre>'; // 表示を見やすく整形する
  var_dump($user); // user変数を一覧表示する
  echo '<pre>';
@endphp
```

```
echo '<pre>'
```
これを前後に付けることで、**var_dumpで一覧表示に改行を入れて見やすくできます。**

ブラウザで確認します。

![スクリーンショット 2022-03-21 0.17.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/769210/ea7b24d2-0d0b-8905-9358-fced091b9693.png)

見やすく一覧表示できました！



## 表示の制御方法

ここからは、先ほどの@foreachや@phpの様な**ディレクティブ**を使って、
渡ってきた**変数の表示を制御する方法**を紹介します。

ちなみに**制御構文はLaravel公式の「制御構文」の部分に分かりやすくまとめられています。**

https://readouble.com/laravel/6.x/ja/blade.html



### 連想配列の値を追加

その前に、連想配列の値をもう少し追加しておきましょう。

```php:VariableController.php
public function test(){
    // title変数を用意
    $title = "ユーザーを全表示";
    // 二次元配列を用意
    $users = [
        [
            'id' => 0,
            'name' => 'テストさん1',
            'gender' => '男性', 
        ],
        [
            'id' => 1,
            'name' => 'テストさん2',
            'gender' => '女性', 
        ],
        [
            'id' => 2,
            'name' => 'テストさん3',
            'gender' => '男性', 
        ],
    ];
    return view('test/test', compact('users', 'title')); // users変数、title変数を渡す
}
```

user変数をusers変数に変更し、中身を追加しました。
また新たにtitle変数も用意しました。

変数が複数でも、**compact関数の場合はコンマで区切ることで複数渡すことができます。**


### @foreach
配列の中身をループさせるディレクティブです。

今回users変数は二次元配列なので、全ての中身を表示させるには@foreachをネストさせましょう。

```php:test/test.blade.php
@foreach($users as $user)
  @foreach($user as $data)
    {{ $data }}
  @endforeach
  <br>
@endforeach

// 表示
// 0 テストさん1 男性
// 1 テストさん2 女性
// 2 テストさん3 男性
```

### @if @else @elseif 

条件に当てはまる場合のみ表示させます。

```php:test/test.blade.php
@if(count($users) === 0)
    <p>ユーザーは0人です。</p>
@elseif(count($users) === 1)
  <p>ユーザーは1人います。</p>
@else
    <p>ユーザーは2人以上います。</p>
@endif

// 表示
// ユーザーは2人以上います。
```


### ループ内で使える$loop変数

**ループの中ではループに関する情報を格納している、$loopという便利な変数が使えます。**

今回は現在のループを何回繰り返したかを格納している**iterationプロパティ**を条件式に使ってみます。

```php:test/test.blade.php
@foreach($users as $user)
  <!-- 条件式 ループが2回以降の場合 -->
  @if($loop->iteration > 2)
    <!-- ユーザー情報をループ  -->
    @foreach($user as $data) 
      {{ $data }}
    @endforeach
    <br>
  @endif
@endforeach

// 表示
// 2 テストさん3 男性
```

他の$loopプロパティは以下になります。

#### $loop変数のプロパティ一覧

| 　　　プロパティ　　　 |　　　　　　　説明 　　　　　　　 |
|:-----------------:|:------------------:|
| $loop->index | 現在のループのインデックス（初期値0） |
| $loop->interation | 現在の繰り返し数（初期値1） |
| $loop->remaining | 繰り返しの残り数 |
| $loop->count | 繰り返し中の配列の総アイテム数 |
| $loop->first | ループの最初の繰り返しか判定 |
| $loop->last | ループの最後の繰り返しか判定 |
| $loop->even | これは偶数回目の繰り返しか判定 |
| $loop->odd | これは奇数回目の繰り返しか判定 |
| $loop->depth | 現在のループのネストレベル |
| $loop->parent | ループがネストしている場合、親のループ変数 |

> 公式より引用
> https://readouble.com/laravel/6.x/ja/blade.html


### @empty

変数が空の場合に表示させることもできます。

```php:test/test.blade.php
@empty($title)
　<p>タイトル中身が空</p>
@endempty

// 表示（title変数が空文字列の場合）
// タイトル中身が空
```



### @isset

@issetは変数が存在し、nullではない場合に表示を行います。

```php:test/test.blade.php
@isset($title)
 <p>変数が存在し、nullではない。</p>
@endisset

// 表示（titleがnullでない場合）
// 変数が存在し、nullではない。
```


### @php

blade内でphp文を書きたい場合は、@phpディレクティブを使います

```php:test/test.blade.php
@php 
  var_dump($users); // phpのvar_dump関数を使いたい
@endphp
```


ただ、**公式より多用するのはあまり良くないとのことです。**

> この機能を提供していますが、数多く使用しているのであれば、それはテンプレートへ多すぎるロジックを埋め込んでいるサインです。



## まとめ

今回は**ControllerからViewへ変数を渡す方法とその変数の表示制御について**まとめました。

Viewに関する理解はある程度深まったように感じます！

ここまでお読み頂きありがとうございました。