xdebug 試す

phpのステップ実行等に使うxdebugを試す。

> Xdebug は、デバッグや開発を支援する PHP 用の拡張モジュールです。
これには、IDE で使用するためのシングルステップデバッガが含まれています。
PHP の var_dump() 関数をアップグレードします。
通知、警告、エラー、例外のスタックトレースを追加します。
すべての関数呼び出しと変数のディスクへの割り当てを記録する機能を備えています。
プロファイラが含まれています。
PHPUnit で使用するためのコードカバレッジ機能を提供します。
https://xdebug.org/


2020年11月15日にメジャーバージョンが上がり3.0.0が公開された。
2系から３系で一部設定が変わったところもあるのでそちらもみていく。

![スクリーンショット 2020-12-17 20.59.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278474/48ace82f-d73a-3b9c-3db5-de2a70a71a41.png)


## インストール
centos8では↓でインストールできる

```
$ dnf install php-pecl-xdebug
```

xdebugをインストールすることでversion情報にxdebugの文字が表示される。

```
 php --version 
PHP 7.4.6 (cli) (built: May 12 2020 08:09:15) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Xdebug v2.9.5, Copyright (c) 2002-2020, by Derick Rethans
```

と思ったら2系がインストールされた。3系が使いたいのでこれはアンインストールする。

```
$ dnf remove php-pecl-xdebug
```

公式サイトによると、PECLかソースコードからインストールすると良いらしい。今回はPECL(PHP Extension Community Library)を試す。
PECLコマンドが入っていないのでインストールする。

```
$ dnf install php-pear -y
$ which pecl
/usr/bin/pecl
```

xdebugをインストール

```
$ pecl install xdebug
WARNING: channel "pecl.php.net" has updated its protocols, use "pecl channel-update pecl.php.net" to update
downloading xdebug-3.0.1.tgz ...
Starting to download xdebug-3.0.1.tgz (214,467 bytes)
.............................................done: 214,467 bytes
87 source files, building
running: phpize
Can't find PHP headers in /usr/include/php
The php-devel package is required for use of this command.
ERROR: `phpize' failed
```

php-develが必要らしい。

> php-develパッケージを利用することで、PHP5の動的拡張機能をコンパイルすることができます。
https://rpmfind.net/linux/rpm2html/search.php?query=php-devel

php-develをインストール

```
$ dnf install -y php-devel
```

他にもmakeが必要らしい。

```
$ dnf install -y make
```

再度xdebugをインストール

```
$ pecl install xdebug
略...
running: find "/var/tmp/pear-build-defaultuserNeMvhr/install-xdebug-3.0.1" | xargs ls -dils
790985    4 drwxr-xr-x 3 root root    4096 Dec 17 14:01 /var/tmp/pear-build-defaultuserNeMvhr/install-xdebug-3.0.1
791093    4 drwxr-xr-x 3 root root    4096 Dec 17 14:01 /var/tmp/pear-build-defaultuserNeMvhr/install-xdebug-3.0.1/usr
791094    4 drwxr-xr-x 3 root root    4096 Dec 17 14:01 /var/tmp/pear-build-defaultuserNeMvhr/install-xdebug-3.0.1/usr/lib64
791095    4 drwxr-xr-x 3 root root    4096 Dec 17 14:01 /var/tmp/pear-build-defaultuserNeMvhr/install-xdebug-3.0.1/usr/lib64/php
791096    4 drwxr-xr-x 2 root root    4096 Dec 17 14:01 /var/tmp/pear-build-defaultuserNeMvhr/install-xdebug-3.0.1/usr/lib64/php/modules
791092 2324 -rwxr-xr-x 1 root root 2377080 Dec 17 14:01 /var/tmp/pear-build-defaultuserNeMvhr/install-xdebug-3.0.1/usr/lib64/php/modules/xdebug.so

Build process completed successfully
Installing '/usr/lib64/php/modules/xdebug.so'
install ok: channel://pecl.php.net/xdebug-3.0.1
configuration option "php_ini" is not set to php.ini location
You should add "zend_extension=/usr/lib64/php/modules/xdebug.so" to php.ini
```

php -vをみてみる。まだxdebugは有効になっていない。メッセージに流れていたようにphp.iniを修正する。
またxdebug.mode=debugと指定してステップ実行できるようにする。

```
php -v
PHP 7.4.6 (cli) (built: May 12 2020 08:09:15) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
```

```php.ini
[xdebug]
zend_extension=/usr/lib64/php/modules/xdebug.so
xdebug.mode=debug
xdebug.client_host = host.docker.internal
```

再度php -v確認。xdebugが有効化された。3.0.1がインストールされている。

```
$ php -v
PHP 7.4.6 (cli) (built: May 12 2020 08:09:15) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Xdebug v3.0.1, Copyright (c) 2002-2020, by Derick Rethans
```


↓他のプラットフォームではこちら
https://xdebug.org/docs/install

## xdebugとIDEの通信

xdebugとIDEの通信を開始するのはxdebugの方からになる。
phpとxdebugをdockerコンテナ等のローカルと違うマシンで動かしている場合、xdebugにIDEへの接続先を指示する必要がある。
使用しているブラウザとIDEが同じホスト上に存在し、php/xdebugが同じサブネット内の別マシンで動いている場合はxdebug.discover_client_hostを1にすればok。xdebugはブラウザからリクエストがくると、ホストのIPを調べ、自動で接続する。

自動接続するのではなく、ホストとポートを指定することも可能。xdebug.client_hostにIDEを実行しているマシンのIPやホスト名を、xdebug.client_portにはTCPポートを指定する。

デフォルトの設定ではxdebugはトリガーが存在する時に起動するが、xdebug.start_with_requestをyesにすることで常にデバッグセッションを開始することも可能。


Xdebug Helper for Chromeという拡張を入れることで、これをONにしている間はリクエストにトリガーを仕込み、デバッグを起動できる。

または、GETやPOSTパラメータにXDEBUG_SESSION=session_nameを追加することでデバッグを起動できる。

xdebugは有効になるとXDEBUG_SESSION クッキーを仕込む。クッキーが存在する限り全てのhttpリクエストに対してデバッグが開始される。
クッキーの有効期限は1時間。
デバッグを終了するにはGETやPOSTニXDEBUG_SESSION_STOP=session_nameを指定する。そうするとxdebugはクッキーを削除する。

また、xdebug.start_upon_error=yesとすることで、phpの警告や例外が投げられた時にxdebugを起動することもできる。



## chrome拡張のインストール
httpリクエストにxdebugを起動するクッキーを追加してくれるchrome拡張をインストールする。

`Xdebug helper`
https://chrome.google.com/webstore/detail/xdebug-helper/eadndfjplgieldjbigjakmdgkmoaaaoc

![Monosnap 2020-12-17 23-48-25.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278474/8caedf63-3b08-6b03-1484-22434dcc2faa.jpeg)
Debugを押すとアイコンが緑色になりDebugが有効かになる。Disableを押すとアイコンが灰色になりDebugが終了する。


## phpstorm
xdebugからの接続要求を受け付ける。電話のアイコンをクリックすると接続受付中になる。
![スクリーンショット 2020-12-17 23.49.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278474/2d63dfae-f894-1901-8847-98f969446744.png)

chrome拡張でdebugが有効になっているが、phpstormで受け付けないとワーニングが出る

```
[Thu Dec 17 14:50:26 2020] Xdebug: [Step Debug] Could not connect to debugging client. Tried: host.docker.internal:9003 (through xdebug.client_host/xdebug.client_port) :-(
[Thu Dec 17 14:50:26 2020] Xdebug: [Step Debug] Could not connect to debugging client. Tried: host.docker.internal:9003 (through xdebug.client_host/xdebug.client_port) :-(
[Thu Dec 17 14:50:26 2020] Xdebug: [Step Debug] Could not connect to debugging client. Tried: host.docker.internal:9003 (through xdebug.client_host/xdebug.client_port) :-(
```

## 実際に使ってみる
↓ブレイクポイントをはる
![スクリーンショット 2020-12-17 23.53.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278474/8a4b521b-7353-f033-217f-0263ff82a11e.png)

↓アクセスすると止まる。
![スクリーンショット 2020-12-17 23.53.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278474/94eb3c7e-db20-5aba-1676-6f02e362c827.png)


## 参考
https://xdebug.org/docs/step_debug
https://pleiades.io/help/phpstorm/browser-debugging-extensions.html