【超入門】Laravelのデバッグ手法22選

## はじめに

[Laravel Advent Calendar 2021](https://qiita.com/advent-calendar/2021/laravel) 7日目の投稿です。
枠があまっていたので1日目に続いて7日目も投稿します。

他の記事のタイトルを見ると応用的な内容が多かったのでLaravel初心者の方向けにおすすめのLaravelデバッグ方法(tips)を22個ご紹介します。

思ったより数が多くなったので、1つ1つは掘り下げず概要と簡単な使い方をご紹介します。
公式ドキュメントや参考リンクも載せているので詳細はそちらを見てください。

どれか一つでもLaravel開発のヒントになれれば幸いです。

## おすすめの手法

特におすすめの方法をご紹介します。

[2.17. テストコードを書く](https://qiita.com/ucan-lab/items/29614d0f3ded1d3a94fb#217-%E3%83%86%E3%82%B9%E3%83%88%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%8F)

一番のおすすめはテストコードを書くことです。
予期する値と実際の値をテストしながらコードを書くことで一つ一つの処理を確認しながら進めることができます。

[2.5. beyondcode/laravel-dump-server](https://qiita.com/ucan-lab/items/29614d0f3ded1d3a94fb#25-beyondcodelaravel-dump-server)

`dump()` と合わせて使うのですがとても便利です。
レスポンスを汚さないので、ストレスフリーに開発できます。

[2.7. tinker](https://qiita.com/ucan-lab/items/29614d0f3ded1d3a94fb#27-tinker)

Laravelのコードを実行できるのでここで実行結果を確認をしつつ、整形してテストコードに残すと良いです。

[2.11. Log](https://qiita.com/ucan-lab/items/29614d0f3ded1d3a94fb#211-log)

Laravel標準でログ機能が実装されています。
システムを運用していく上で欠かせないログですが、Laravelでは柔軟に設定できます。

## 1. PHP標準関数の紹介

### 1.1. var_dump

[var_dump](https://www.php.net/manual/ja/function.var-dump) 関数はPHPの標準関数です。
指定した変数をダンプします。

```php
var_dump($value);

var_dump($value1, $value2, $value3, ...);
```

変数に関する情報をダンプします。
https://www.php.net/manual/ja/function.var-dump.php

```
var_dump($value);
die; // exit;
```

処理を止めたい時は [die](https://www.php.net/manual/ja/function.die.php) または [exit](https://www.php.net/manual/ja/function.exit.php) します。

他にもPHPの標準関数として [var-export](https://www.php.net/manual/ja/function.var-export)、[var_representation](https://www.php.net/manual/ja/function.var-representation)、[print-r](https://www.php.net/manual/ja/function.print-r)等ありますが、基本は`var_dump`が使えれば良いでしょう。

### 1.2. debug_print_backtrace

[debug_print_backtrace](https://www.php.net/manual/ja/function.debug-print-backtrace.php)
関数はPHP標準関数です。
`debug_print_backtrace()` までの実行過程(バックトレース)で呼び出されたファイル名、関数名、クラス名、引数のリストを表示します。

```
debug_print_backtrace();

debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
```

引数まで出力するとさすがに情報量が多くなるので、 `DEBUG_BACKTRACE_IGNORE_ARGS` オプションを付けると見やすくなります。

[debug_backtrace](https://www.php.net/manual/ja/function.debug-print-backtrace.php)

こちらはバックトレースの情報を配列で返す関数です。

### 1.3. マジック定数を使うtips

```
var_dump(__CLASS__ . '::' . __FUNCTION__ . '#' . __LINE__);
=> string(45) "App\Http\Controllers\BookController::index#21"
```

`var_dump('aaa');` のように適当にたくさん仕込むとどこのやつだっけ？
となるので上のようにしておくとどこを通ったか分かりやすくなるのでおすすめです。`__CLASS__` の代わりに `__FILE__` も便利

https://www.php.net/manual/ja/language.constants.magic.php

### 1.4. Xdebug

https://pecl.php.net/package/xdebug
https://xdebug.org

Xdebugを導入するとステップデバッグ、トレース、プロファイリング等が行えます。
Xdebugを動作させるにはPHP拡張機能のインストールやブラウザやIDEでXDebugの各種設定が必要です。

## 2. Laravelデバッグ手法の紹介

### 2.1. dump

`dump` 関数はLaravelのヘルパー関数です。
指定した変数をダンプします。

```php
dump($value);

dump($value1, $value2, $value3, ...);
```

https://readouble.com/laravel/8.x/ja/helpers.html#method-dump

### 2.2. dd (dump die)

`dd` 関数はLaravelのヘルパー関数です。
指定された変数の内容を表示し、スクリプトの実行を停止します。

```php
dd($value);

dd($value1, $value2, $value3, ...);
```

おそらく一番お世話になる関数。

### 2.3. ddd (dump die debug)

`ddd` 関数は[facade/ignition](https://github.com/facade/ignition)のヘルパー関数です。

`dd` 関数の結果を含む、スタックトレース、リクエスト及びIgnitionページで提供されるタブの情報を表示します。

Laravel6.x以降で利用可能です。

```php
dd($value);

ddd($value1, $value2, $value3, ...);
```

dumpした結果の他にDBクエリー情報等も見れて結構便利

https://laravel-news.com/ddd-helper

### 2.4. report

`report`関数は[例外ハンドラ](https://readouble.com/laravel/8.x/ja/errors.html#the-exception-handler)を使用して例外をレポートします。

```php
report('Something went wrong.');

report($e);
```

`report`関数は `string` もしくは `Throwable` を引数として受け取ります。
例外のログを出力しつつ、処理を継続します。

画面に例外を表示することなく、例外をログ出力できるのでバックトレースの確認がしやすいです。
ただし、例外が発生しても処理を継続する挙動になるので利用には注意が必要そうです。

https://readouble.com/laravel/8.x/ja/helpers.html#method-report

### 2.5. beyondcode/laravel-dump-server

https://github.com/beyondcode/laravel-dump-server

Symfonyの[Var-Dump Server](https://symfony.com/doc/current/components/var_dumper.html#the-dump-server)をLaravelに組み込んだライブラリです。

`dump` 関数を実行する際、HTTP/APIのレスポンスに干渉しないように`dump`の実行結果をダンプサーバーへ出力します。

### 2.6. php -a (対話シェル)

`-a` オプションを付けてphpを実行することで対話シェルを使えます。
対話シェルを使うと、PHPのコードを打ち込んで直接実行できるようになります。

```
$ php -a

php > $a = 60 * 60;
php > echo $a;
3600
```

https://www.php.net/manual/ja/features.commandline.interactive.php

### 2.7. tinker

Laravelに標準搭載されている対話シェルです。
[psysh](https://psysh.org)のラッパーライブラリです。

LaravelのちょっとしたLaravelのコードを対話シェルで実行したい時に使えます。

- https://github.com/laravel/tinker
- [Laravel 標準搭載のデバッグ機能 tinker コマンドのご紹介](https://qiita.com/ucan-lab/items/0e9537be6d5709e1d099)
- [Laravel コントローラをtinkerから実行する](https://qiita.com/ucan-lab/items/da3441b7a9e5c79f759d)
- [Laravel tinker で Faker を試す方法](https://qiita.com/ucan-lab/items/bc421788d4a352afc6ea)

### 2.8. spatie/laravel-web-tinker

https://github.com/spatie/laravel-web-tinker

ブラウザ上でtinkerコマンドを実行できるライブラリです。
GoogleAppEngine上など直接SSHできない環境等でこれを入れておくとお手軽にデバッグできます。

これを入れたまま本番を動かすのは良くないので注意しましょう。

### 2.9. Tinkervel

https://tinkervel.com

Laravelのちょっとした動作確認をすることができるツールです。
コードの実行結果をサーバに保存し、シェアできます。
@mikkame さんが開発してます。

### 2.10. Tinkerwell

https://tinkerwell.app

有償アプリですが、Tinkerをデスクトップアプリから実行できるツールです。
ローカルのPHPの実行、SSH経由でリモートのPHPを実行できます。

### 2.11. Log

https://readouble.com/laravel/8.x/ja/logging.html

`var_dump` などのデバッグコードを残したまま納品はできないので、気になる部分はログを残すようにします。

LaravelではLogファサードやヘルパー関数が用意されておりログ出力が簡単に行えます。

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

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

// ヘルパー
logger($message); // debugレベル
info($message); // infoレベル
logger()->error($message); // 任意のレベル

// 関連情報を第二引数として渡せる
Log::debug($message, ['id' => $user->id]);
```

#### Log: ログ出力先

Laravelのログはデフォルト(single)では `storage/logs/laravel.log` へ出力されます。

```shell-session
$ less +F storage/logs/laravel.log
```

`less +F` で監視モードでログファイルを開けるのでログ用にターミナルを起動しておくと便利です。

#### Log: 設定ファイル

[config/logging.php](https://github.com/laravel/laravel/blob/8.x/config/logging.php) にログ周りの設定ファイルがあります。
また、 `.env`環境変数ファイルから `LOG_CHANNEL` でログチャンネルを切り替えたり、`LOG_LEVEL` ログ出力レベルを変更できます。

`stack` チャンネル
複数のチャンネルにログ出力できます。
デフォルトでは `single` チャンネルのみに出力する。

`single` チャンネル
単一のログファイルに追記されます。
`storage/logs/laravel.log`

`daily` チャンネル
日毎にログファイルをローテートしてくれます。
`storage/logs/laravel-YYYY-MM-DD.log`

`null` チャンネル
ログメッセージを破棄します。(ログの無効化ができます)

他にもチャンネルがあるので詳しくは公式ドキュメントをご参考ください。
https://readouble.com/laravel/8.x/ja/logging.html

※Laravel5.5以前とはログの仕組みが大きく変わっているので古いLaravelの場合は注意が必要です。

### 2.12. Query Log

```php
$query = \App\User::where('id', 1);
dd($query->toSql(), $query->getBindings());
```

```php
\DB::enableQueryLog();
\App\User::all();
dd(\DB::getQueryLog());
```

[Laravel SQLの実行クエリログを出力する](https://qiita.com/ucan-lab/items/753cb9d3e4ceeb245341)

### 2.13. laravel-ray

https://myray.app
有償のデバッグデスクトップアプリのRayです。
Windows, Mac, LinuxのOS上で動作します。

見た目が洗練されていて、Laravelで使う場合はPHP拡張機能を追加する必要はなくComposerでライブラリをインストールするだけでokです。

XDebugほど高機能ではないですがブレークポイントを貼ることもできます。
実行速度の計測用ヘルパーが用意されていてデバッグするのに役立ちます。

[ミライトデザイン Advent Calendar 2021](https://qiita.com/advent-calendar/2021/miraito-inc)の18日目に紹介記事を書かせていただきました。

[Laravel Ray 進化したDumpデバッグデスクトップアプリ](https://qiita.com/ucan-lab/items/a51393db3d421bf78a57)

```php
ray($anything);
ray($anything, $somethingElse);
ray($anything)->green();
ray()->queries();
ray()->measure();
ray()->trace();
ray()->pause();
ray()->ban();
```

https://github.com/spatie/laravel-ray

### 2.14. barryvdh/laravel-debugbar

https://github.com/barryvdh/laravel-debugbar

クエリ実行ログ、ルーティング、ビュー、セッション等の様々な情報をデバッグバーとして出力してくれます。
Blade開発時に効果を発揮します。

### 2.15. beyondcode/laravel-debugbar-companion

https://github.com/beyondcode/laravel-debugbar-companion

デバッグバーのデスクトップアプリです。
デバッグバーをより便利に使いたい人はご検討ください。
(しばらくBlade触ってないので筆者は使ったことないです...)

### 2.16. laravel/telescope

https://readouble.com/laravel/8.x/ja/telescope.html

Telescope（テレスコープ：望遠鏡）は、ローカル開発環境のデバッグツールです。
デバッグバー同様、様々な情報を出力してくれます。
API開発時に効果を発揮します。

### 2.17. テストコードを書く

https://readouble.com/laravel/8.x/ja/testing.html

テストコードは自分の書いたコードが、想定通りに動いているか確認するためのものです。
不具合を再現させるテストコードを書いて、実コードを修正すると再発防止になります。

最初からテストコードを書くのは難しいですが、テストコードがあるとより効率的に開発を進めることができます。
手始めにtinkerで動作確認した内容をテストコードにしていくと良いと思います。

## 3. ブラウザの開発者ツール

### 3.1. Chromeデベロッパーツールを使いこなそう

[技術書典](https://techbookfest.org)で良書を見つけたのでご紹介します。

[Chromeデベロッパーツールを使いこなそう Console編](https://booth.pm/ja/items/1054598)
[Chromeデベロッパーツールを使いこなそう Network編](https://booth.pm/ja/items/1310814)
[Chromeデベロッパーツールを使いこなそう Elements編](https://booth.pm/ja/items/1573848)

ConsoleとNetworkの見方や使い方を知るとデバッグが捗るので読んで損はないと思います。