Laravelでのデバッグ方法4パターンまとめ

Laravelのデバッグ方法って何かいっぱいあるよね...

## なぜこの記事を書こうと思ったか
少しでも開発を効率化する為です。
僕自身のメモ用っていうのもあるんですが、パターンに応じてどのデバッグ方法を使うのがベストかというのが分からないんですよね😂
その時にどんな選択肢があるかも知っておきたかったので、記事にまとめようと思いました！
間違っているもの、他にもこんな方法があるよ！とかあれば是非教えて頂ければ助かります:bow:

## 環境
```bash:ターミナル
$ php artisan --version
Laravel Framework 5.5.50

$ php -v    
PHP 7.1.33 (cli) (built: Oct 31 2019 17:37:57) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies

$ composer -v
Composer version 2.0.12 2021-04-01 10:14:59

```

### 1. Logファサード

Logファサードを使用して、ログに変数の値などを出力するやり方。
簡単でお手軽です。

使用したいControllerなどで、下記をUseに指定します(Blade内でも使えます)

```php3
use Illuminate\Support\Facades\Log;
```

あとは、Logファサードを使用し

```php3

// 変数
Log::debug($test);

// 配列
Log::debug(print_r($arr, true));

// オブジェクト
Log::debug(print_r($object, true));

```
のように出力します。
useを使用しない場合は、下記のように「\」を先頭につければ指定しなくても出力できます！

```php3
\Log::debug($test);
```

<br>
出力する際のメソッド（ログレベル）は下記の通り。

```php3:
Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);
```

上から順にレベル（緊急度）が高く、下記のように設定ファイル（`config/app.php`）にレベルを記述しておくと、そのレベルより上のログしか出力されなくなるとのこと。

```php3:config/app.php
'log_level' => env('APP_LOG_LEVEL', 'debug'),
```
以下、公式より引用。
>Laravelはデフォルトで全ログレベルをストレージに書き込みます。
しかし、実働環境ではapp.php設定ファイルのlog_levelオプションへ、ログすべき最低の重大さレベルを指定したいことでしょう。
このオプションを一度設定すると、Laravelは指定された重大さ以上の全レベルをログします。
たとえば、log_levelにerrorを設定すると、error、critical、alert、emergencyメッセージがログされます。

開発環境だと、debugだけ使用してログを出力して本番環境はそれ以外で出力するみたいな使い方かな:thinking:

出力場所は、デフォルトで`storage/log/laravel.log`に出力されます。
もし日次でファイルを分けたいなら、`config/app.php`に下記のように設定すれば分かれます:ok_woman:

```php3:config/app.php
'log' => 'daily'
```


### 2. Tinker

Laravelに標準で組み込まれているようなので、特に準備せずに使えるようです！
(名前ディズニーのキャラみたいでカワイイ👼)

ターミナルで、下記コマンドを叩きます。

```bash:ターミナル
$ php artisan tinker
Laravel Framework 5.5.50
bash-4.2# php artisan tinker
Psy Shell v0.9.12 (PHP 7.1.33 — cli) by Justin Hileman
>>> 
```

すると上記のように入力待ちの状態になるので、あとはphpのコマンドを入力すれば実行結果が返ってきます。

```bash:ターミナル
>>> array ('a' => '1', 'b' => '2', 'c' => '3');
=> [
     "a" => "1",
     "b" => "2",
     "c" => "3",
   ]
```

変数に値を格納して、操作することも可能。

```bash:ターミナル
>>> $hoge = new Carbon\Carbon('now');
=> Carbon\Carbon @1618184500 {#4459
     date: 2021-04-12 08:41:40.625537 Asia/Tokyo (+09:00),
   }
>>> $hoge->dayOfWeek
=> 1
>>> $hoge->addDay();
=> Carbon\Carbon @1618270900 {#4459
     date: 2021-04-13 08:41:40.625537 Asia/Tokyo (+09:00),
   }
```

終了するには、 exit

```bash:ターミナル
>>> exit
Exit:  Goodbye
```

* ちょっとphp標準のメソッドの動きを確認したい
* オブジェクトの中身を確認したい

と言った「**画面を動かすまでもないけど実行結果を見たい**」という場合には有効に使えそう。
個人的には、Carbonの動きとか把握するのにかなりありがたい存在😊

~~プロジェクト内で、**public static functionを定義していればそれも使える**ようです。~~
※追記 public static以外のメソッドもNewすれば使えるようです。
コメントで教えて頂いた @nunulk さんありがとうございました:bow_tone1:

```php3
>>> $hoge = new \App\Hoge()
=> App\Hoge {#1000}
>>> $hoge->piyo()
=> "piyo"
>>
```

### 3. Debugbar

こちらはめちゃくちゃ有名なので、導入している方も多いかと思います。

#### 準備

下記コマンドでインストールします。基本的に、本番環境で有効とすることはないと思うので、インストール時は`--dev`を付与すると良いでしょう。

```bash:ターミナル
composer require barryvdh/laravel-debugbar --dev
```

.envでは、`APP_DEBUG`もしくは`DEBUGBAR_ENABLED`をtrueに設定します(本番環境ではfalseに戻すのを忘れずに)

`APP_DEBUG=true`とするだけでDebugbarは有効化されますが、`DEBUGBAR_ENABLED`が設定されていれば、そちらが優先されます（例えば、`APP_DEBUG=true`と設定しても、`DEBUGBAR_ENABLED=false`という設定があれば、そちらが優先され、Debugbarは機能しません）。

```bash:.env
# 基本の設定
APP_DEBUG=true

# APP_DEBUGの設定と、Debugbarの設定を分けたいときは、DEBUGBAR_ENABLEDを設定する。
# 分ける必要がない場合は、DEBUGBAR_ENABLEDは不要。
DEBUGBAR_ENABLED=true
```

~~忘れないように、envの値を反映させます~~
※追記
このタイミングで私は `php artisan config:cache`していたのですが、開発環境でconfigをキャッシュするのは推奨されないとのことなので、cacheしていない場合は特になにもしなくてOKです！

以下、公式より引用。
>一般的には、本番環境へのデプロイ作業の一環として、php artisan config:cacheコマンドを実行すべきでしょう。
アプリケーションの開発期間中は設定が頻繁に変更されることも多いので、ローカルでの開発中にこのコマンドを実行してはいけません。
Note: 開発過程の一環としてconfig:cacheコマンド実行を採用する場合は、必ずenv関数を設定ファイルの中だけで使用してください。
設定ファイルがキャッシュされると、.envファイルはロードされなくなり、env関数の呼び出しは全てnullを返します。

・config:cacheすると、envファイルはロードされなくなる
・env関数を設定ファイル以外で使っている場合は、nullになってしまう
ってことですね。
既にcacheしてしまっている場合は、下記コマンドでクリアします。

```bash:ターミナル
php artisan config:clear
```

コメントで教えて頂いた @kaya754 さん、ありがとうございました！

準備は以上です。

#### 使い方
ブラウザにアクセスすると、ページの下部にデバッグバーが表示されます。

![スクリーンショット 2021-04-13 8.11.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682425/d6e4d5eb-feb0-2d28-0b55-2a8267913ebd.png)

それぞれタブごとに様々な情報が表示されますが、よく使うタブは下記の通りです。

| タブ | 内容 | 
|:-------------------|:----------------------------------|
| Messages    | 出力したログの確認        | 
| Views       | レンダリングされたViewの一覧      | 
| Route       | ルーティング関係の一覧        | 
| Query       | 裏で走っているSQL          | 
| Session     | Sessionの一覧と値       | 
| Request     | Requestの一覧と値     | 

Messagesには、デバッグバーの下記メソッドでログを出力できます。

```php3:
\Debugbar::emergency('emergency');
\Debugbar::alert('alert');
\Debugbar::critical('critical');
\Debugbar::error('error');
\Debugbar::warning('warning');
\Debugbar::notice('notice');
\Debugbar::info('info');
\Debugbar::debug('debug');
\Debugbar::log('log');
```

出力してみるとこんな感じです。
![スクリーンショット 2021-04-13 8.41.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682425/fe06e08a-df5e-f820-6310-8b4edfda1ee3.png)
一番上の行にあるように、Logファサードで出力したログもこちらで見れるみたいです😃
いちいちlaravel.logを見るよりこっちの方が簡単ですね。

![スクリーンショット 2021-04-14 7.46.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682425/1d5f7dee-8238-d802-873c-3540479c8f1f.png)
Viewsは、実際にシステムを動かして、このページを編集したいという時にViewを特定するのに便利かな！

![スクリーンショット 2021-04-14 7.46.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682425/b3ccdbde-6a90-09d3-dad4-9edc552890b4.png)
Routeは、ルーティングの確認に便利。
web.phpを見ても良いんですが、大きなシステムだとコードを多すぎて1ページでは情報が把握しきれない事があるんですよね😂

QueryではSQLが把握できます。
**Laravelで開発している時ってSQLがどれだけ走ってるかとか意識しづらい**と思うんですが、確認してあげる事でN+1問題等にも気付けるんじゃないかと思います。

SessionやRequestは、コード上だけでは分かりづらい中身が見れるのでめっちゃありがたい。
モデルを返した時に、コレクションで返ってきてる事が分かりますね。

これ以外にもタブは幾つかありますが、僕自身まだあまり使いこなせていないので、もっとこんな事もできるとかあれば教えてほしいです:point_up:


### 4.ヘルパーメソッド
dump()もしくはdd()を使って、値をブラウザ上に出力する方法です。
２つの違いは、
・dump()は、**処理が止まらずに出力するだけ**
・dd()は、**記述時点で処理が止まる**
って感じらしい。
使い方はめちゃ簡単で、引数に出力したい値を渡すだけ。

```php:
$test = new Carbon\Carbon('now');
dump($test);
```

この状態でブラウザにアクセスすると、上部にバーが表示されてログが出力されます。
![スクリーンショット 2021-04-14 7.55.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682425/5989ff2c-a8c2-19dd-041e-e8f4524dbe2f.png)
ページを見ながら値を確認できるので、分かりやすいですね😊

View側で`Controllerから渡ってきた値を確認したい`という事もあるので、Viewで書けないのかな？と思いましたが、Viewでも下記にように書けば使えるようです！

```php3
<div id="wrapper">
	<div class="head-information head-margin-top">
        <h2>テストページです</h2>
        @php
            $test = new Carbon\Carbon('now');
            dump($test);   
        @endphp
	</div>
</div>
```
ただし、Viewで書くと記述した場所に出力されるので、デザインが崩れる可能性はありますｗ
![スクリーンショット 2021-04-14 8.07.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682425/3e5ad434-fc13-dc04-fbf8-d58b6efc0e00.png)

今度は、Contoller側にてdd()で出力してみます。

```php3
    public function index()
    {
        $test = new Carbon('now');
        dd($test);

        return view('page.mypage.dashboard.test');

    }
```

すると、ページが表示されずにログだけページに表示されるのがわかります。
![スクリーンショット 2021-04-14 8.12.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682425/d59d177b-6941-0865-35dc-abe232e66a0c.png)

**dd()では書いた場所で処理が止まる**ので、上記のコードではreturn Viewが行なわれてないことが分かります。

View側でdd()を書くとどうなるか...

```php3
<div id="wrapper">
    <div class="head-information head-margin-top">
        <h2>テストページです</h2>
        @php
            $test = new Carbon\Carbon('now');
            dd($test);
        @endphp
    </div>
    <h1>さすがディオ！おれたちにできない事を平然とやってのけるッ そこにシビれる！ あこがれるゥ！</h1>
</div>
```
![スクリーンショット 2021-04-14 8.27.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682425/709c50be-02da-3243-62f0-baae44bb47ae.png)
途中で読み込みが終わっているので、`ジョジョの名言が出力されていない`ことが分かりますね( ・∀・)!!
divタグも閉じられていない事になっているので、クラス名に対してCSSも適用されていない:thinking:
View側でdd()を使う事はあまりなさそうですが、`Viewでエラーになっている箇所の手前で使う`という使い方はできそうです。

## 個人的まとめ
* 基本は、`dump()`でログ出力
* エラー箇所の手前で処理を止めたい場合は、`dd()`
* dump()だとViewのデザインが崩れて困るという場合は、`debugbar`にログ出力
* タスクスケジューラ等、画面を必要としない処理は`Logファサード`
* LaravelやPHPのメソッド、自作モデルやメソッドの動きを確認したい場合は`Tinker`

## 参考
[laravel-debugbar](https://github.com/barryvdh/laravel-debugbar "laravel-debugbar")
[Laravel 5.5 Artisanコンソール](https://readouble.com/laravel/5.5/ja/artisan.html "Laravel 5.5 Artisanコンソール")
[Laravel 5.5 パッケージ開発](https://readouble.com/laravel/5.5/ja/packages.html "Laravel 5.5 パッケージ開発")
[Laravel 5.5 エラーとログ](https://readouble.com/laravel/5.5/ja/errors.html " 
Laravel 5.5 エラーとログ")
[laravelデバッグバーの導入](https://laraweb.net/environment/1196/ " 
laravelデバッグバーの導入")
[Laravel 5.5 設定](https://readouble.com/laravel/5.5/ja/configuration.html "Laravel 5.5 設定")


## 終わりに
軽く調べた感じは他にもデバッグ方法はありそうでしたが、ひとまずこれだけ知っていれば大抵のパターンで困らないんじゃないかな〜と思う！
もっと便利なやり方があれば、使いたい所存😃