Laravel PHP デバッグ やり方 [検索]

こんにちは。やまゆです。

Laravel や PHP のロジックをデバッグしたい時に使える機能をリストアップしてみました。

IDE と xdebug 等を併用した高度なステップ実行デバッグなどではなく、素朴に出力する系についてまとめています。

## PHP 汎用

### echo

[PHP: echo - Manual](https://www.php.net/manual/ja/function.echo.php)

グローバル関数ではなく言語構造です。

これを書いた場所で標準出力に流れます。引数は文字列のみ可能なので、 array とか入れても Array としか表示されません。

```php
echo ['a'];
Warning: Array to string conversion in /in/35K9M on line 3
Array
```

まあ、あまり使うことはないでしょう。

### print_r()

[PHP: print_r - Manual](https://www.php.net/manual/ja/function.print-r)

渡された変数をまあまあ綺麗に出力してくれる奴です。

これを書いた場所で標準出力します。

```php
print_r([1, 2, 3]);
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
)

$a = new stdClass();
$a->b = 'C';
print_r($a);
stdClass Object
(
    [b] => C
)
```

たまに使うかも

### var_dump()

[PHP: var_dump - Manual](https://www.php.net/manual/ja/function.var-dump.php)

デバッグ用途で、渡された可変長の変数を分かりやすい形で出力します。

```php
var_dump(1, [2, 3], ['4' => '5', '6' => ['7', '8']]);
int(1)
array(2) {
  [0]=>
  int(2)
  [1]=>
  int(3)
}
array(2) {
  [4]=>
  string(1) "5"
  [6]=>
  array(2) {
    [0]=>
    string(1) "7"
    [1]=>
    string(1) "8"
  }
}

class A { public $b = 0; private $c = 1.5; }
$a = new A;
var_dump($a);
object(A)#1 (2) {
  ["b"]=>
  int(0)
  ["c":"A":private]=>
  float(1.5)
}
```

これは結構有用なので、使っている方も多いんじゃないでしょうか。再帰的に出力してくれるので、ネストが深い配列やクラスでも中身を覗くことが出来ます。

代わりに、大きいクラスのインスタンスや再帰的に変数を保持しているインスタンスを var_dump に投げると、出力がかなり長くなってしまって逆に見づらいので注意です。

### var_export()

[PHP: var_export - Manual](https://www.php.net/manual/ja/function.var-export)

var_dump と似ていますが、これは出力が「PHPコードとして valid である」という部分に違いがあります。
例えば配列を出力したら、その出力文字列を [eval](https://www.php.net/manual/ja/function.eval) することが出来ます（普通しないと思いますが）。

また、第二引数に `true` を渡すことで、標準出力するのではなく、戻り値として文字列を取得することも出来ます。テキストログに吐きたい時に使うこともありますね。

### xdebug

[Xdebug - Debugger and Profiler Tool for PHP](https://xdebug.org/)

ブレイクポイントを張れる高機能なデバッグ用のPHPエクステンションです。

ブレイクポイントとは、指定した行を実行するタイミングで処理を一時的に停止して、その場で宣言されている変数の中身を見たり、書き換えたり、ステップ実行(処理を1つずつ順番に実行していく)したりすることが出来ます。

この資料で詳しく書くとここだけ長くなってしまうので、使い方など詳細については省略いたします。

### phpdbg

php のコアリポジトリに同梱されているデバッグ用のPHPエクステンションです。 xdebug と同様ブレイクポイントを張ることが出来ます。

あまり情報がなくて謎が多いんですが、とりあえず **PHPUnit のカバレッジを出すのが楽** という利点があります。

```sh
$ phpdbg -qrr vendor/bin/phpunit --coverage-html=storage/coverage
```

これだけでカバレッジを HTML に出力してくれます。 xdebug でカバレッジを取るよりも数倍高速です。

カバレッジを取りたいだけであれば、最近は [pcov](https://github.com/krakjoe/pcov) というツールがさらに早いらしいです。

## Laravel 向け

※Laravel 8.x より古いバージョンでは搭載されていない機能もあります
※symfony でも一部使えたり、ライブラリを require したら使えたりするものもあります

### d()

[symfony/var-dumper: The VarDumper component provides mechanisms for walking through any arbitrary PHP variable. It provides a better dump() function that you can use instead of var_dump().](https://github.com/symfony/var-dumper)

symfony/var-dumper の `dump` ヘルパー関数の省略形です。渡した変数の中身を表示してくれます。

### dd()

出力されるものは `d` と同じですが、この関数は出力後に `exit(1);` してその時点で処理を停止させます。

### ddd()

- [spatie/laravel-ignition: A beautiful error page for Laravel apps](https://github.com/spatie/laravel-ignition)
- https://github.com/spatie/laravel-ignition/blob/main/src/helpers.php

オシャレなエラーページを表示してくれるライブラリです。

```php
// コード内にこういうのを書く
ddd($mitaiHensuu, $userId, $sonota);
```

この関数を呼ぶだけで、 HTML 整形された綺麗なレスポンスを表示してくれます。

![](https://camo.githubusercontent.com/5f5b540601aeef5820dac223125d3a5d11e91e81ae00880452b6e3964c94396a/68747470733a2f2f7370617469652e6769746875622e696f2f6c61726176656c2d69676e6974696f6e2f696d616765732f73637265656e73686f742e706e67)

### whoops

[filp/whoops: PHP errors for cool kids](https://github.com/filp/whoops)

以前の Laravel ではこのライブラリが同梱されていました。現在は上の ignition に移行しています。

### laravel-debugbar

[barryvdh/laravel-debugbar: Laravel Debugbar (Integrates PHP Debug Bar)](https://github.com/barryvdh/laravel-debugbar)

Web アプリケーション(=ECサイトとか、 html をレスポンスとするもの)では必須で入れていいんじゃないかレベルのものです。デバッグバーが開いて勝手に情報収集してくれます。

![](https://user-images.githubusercontent.com/973269/79428890-196cc680-7fc7-11ea-8229-189f5eac9009.png)

元になっているのは https://github.com/maximebf/php-debugbar です。

### ログファイルに書き込む

ログファイルに書き込んで、それを確認するのも手です。

```php
Log::debug('■■■デバッグ■■■', ['id' => $id, 'userName' => $userName, 'master' => collect($master)]);
```

第二引数に配列でコンテキストを渡せるので、そこに変数を入れるとうまい具合に変換してくれます。

## REPL(Read-Eval-Print Loop)

対話型シェル(インタラクティブシェル)と呼ばれるものです。標準入力を eval して、その場で実行結果を表示させることが出来ます。

### php -a

PHP コア機能の REPL です。使い勝手は正直微妙です。

```
$ php -a
Interactive shell

php > $a = 2;
php > echo $a;
2
php > 
```

### PsySH

- [PsySH](https://psysh.org/)

デファクトスタンダード的なインタラクティブシェルです。

```
$ vendor/bin/psysh 
Psy Shell v0.11.1 (PHP 8.1.6 — cli) by Justin Hileman
New version is available (current: v0.11.1, latest: v0.11.5)
>>> $a = 2;
=> 2
>>> echo $a;
2⏎
>>> 
```

### Laravel tinker

Laravel に同梱されている REPL です。中身は上記の Psysh ですが、 Laravel のアプリケーションが後ろで初期化されるので、 `app($className)` で DI コンテナからオブジェクトを引っ張ったりすることが出来ます。

```
$ php artisan tinker
Psy Shell v0.11.1 (PHP 8.1.6 — cli) by Justin Hileman
>>> $a = 1;
=> 1
>>> echo $a;
1⏎
>>> 
```


---

Laravel アプリケーションのデバッグでは、 `dd()` 関数、 `ddd()` 関数と `tinker` が楽で便利に使えるのでオススメです。


## 参考資料

- [PHP: PHP のデバッグ - Manual](https://www.php.net/manual/ja/debugger.php)