[メモ] Windows 11 + WSL2(Ubuntu) + Docker + php container + VSCode 環境でXdebugを導入

※履歴に、都合の悪い情報が残っちゃったので、再投稿です。
※意味深な事を書いていますが、単にProject名とかが履歴に残っちゃったってだけですわ

# まえがき
みんなが嫌うJavaエンジニアなので、ステップ実行ができないと心が病んでしまう人間です。

WebエンジニアはみんなMacを使っていると思いますが、私は慣れ親しんだWindowsで仕事をしています。
普通はそんなに苦戦しないであろうXdebugの導入に苦戦したので、2023年3月1日版として、あちこちから引用しつつ、Xdebugを導入した手順を残してみます

# 参考とさせていただいた資料
- https://helog.jp/php/wsl2-docker-xdebug-vscode/
- https://tako.nakano.net/blog/2022/03/wsl2-php-xdebug3/
- https://zenn.dev/datsukan/articles/a479f3e98a70c4

↑を見たほうが良いかも感はあるわね！

# 環境
Xdebug導入済みの環境なので、参考程度に

- Widnows 11 Pro 22H2 22621.1265
Hyper-VがON/OFFとか、そのあたりの設定は確認してないです

- WSL2 
```
$ wsl --version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47
MSRDC バージョン: 1.2.3575
Direct3D バージョン: 1.606.4
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windowsバージョン: 10.0.22621.1265
```

- Docker関連
```
$ docker --version
Docker version 20.10.23, build 7155243

$ docker-compose --version
Docker Compose version v2.5.0
```
- PHP
※仕事の開発環境なので、細かいところは割愛しますが・・・
※docker-composeでphp公式Image？php-apache？を引っ張ってきて、OPcacheが入っていたりします
※Xdebug導入済みですが、このメモ内にXdebugのインストール手順も入ってます
```
$ docker-compose exec php php --version
PHP 8.1.12 (cli) (built: Oct 28 2022 18:29:05) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.12, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.12, Copyright (c), by Zend Technologies
    with Xdebug v3.2.0, Copyright (c) 2002-2022, by Derick Rethans
```

- VSCode
気休めなのか、気休めじゃないかわかりませんが、VSCodeはon WSLで動かしています
```
バージョン: 1.75.1 (user setup)
コミット: 441438abd1ac652551dbe4d408dfcec8a499b8bf
 日付: 2023-02-08T21:32:34.589Z
Electron: 19.1.9
Chromium: 102.0.5005.194
Node.js: 16.14.2
V8: 10.2.154.23-electron.0
OS: Windows_NT x64 10.0.22621
Sandboxed: Yes
```

# 手順
## VSCodeにPluginをインストール
どこのボタンを押したらインストールできるかなどは割愛しています。
拡張機能で以下をインストール
- WSL v0.75.3
- PHP Debug v1.32.0
どれも、公式バッチがついているものをインストールしています

## PHP container用に、php.iniを準備＋マウント
適当なところに（※docker-compose.ymlでマウントするので、できる場所に置きましょう）、php.iniファイルを作成
```phpo.ini
[xdebug]
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.discover_client_host=false
#xdebug.client_host=host.docker.internal
xdebug.client_host=172.25.34.80
xdebug.client_port=9003
xdebug.idekey="VSCODE"
```
ポイントは `xdebug.client_host=172.25.34.80` のところ。
各サイトでは `host.docker.internal` で行ける！と書いてある（ネットワークをちゃんと設定していればDockerがホスト名解決してくれる）のですが、私の環境ではダメでした

```docker-compose.yml
: 前略
  php:
    container_name: ...
: 中略
    volumes:
      - "./docker/php.ini:/usr/local/etc/php/php.ini"
    extra_hosts:
      - "host.docker.internal:host-gateway"
: 後略
```
extra_hostsでホストのIPが自動で登録される（たぶん、container内のhostsファイルに）っぽいですが、ホスト側で待ち受けているXdebugに通信が行かなかったのよ。

./docker/php.ini は、先程作成したphp.iniファイルです

## containerを立ち上げて、Xdebugをインストール
container起動はSKIPします。 `docker-compose up -d` とか叩けばいいと思います

私の環境では、phpというサービス名でphp環境を立ち上げているので、phpに対してインストール作業を行います
```bash
docker-compose exec php bash -c ' \
apt-get upgrade -y \
&& apt-get update -y \
&& apt-get install -y \
        autoconf \
        dpkg-dev \
        file \
        g++ \
        gcc \
        libc-dev \
        make \
        pkg-config \
        re2c \
        ca-certificates \
        curl \
        xz-utils \
    --no-install-recommends \
&& pecl install xdebug && docker-php-ext-enable xdebug \
'
```

Xdebugだけインストールしようとすると
```
ERROR: `phpize' failed
```
と怒られたので、必要なものを色々と入れています

## VSCodeの設定
引用
> VSCodeの左メニューから「実行とデバッグ」アイコンをクリックすると、「実行とデバッグをカスタマイズするには、launch.jsonファイルを作成します。」というメッセージが表示されるので、メッセージをクリック、さらに「PHP」を選択してファイルを生成します。
> 
> .vscode/launch.json
> 
> ファイルを編集して、項目「hostname」と「pathMappings」を追記します。
> 「workspaceRoot」はVSCodeのルートです。コンテナのルートに合わせて、該当のソースが特定できるように設定します。

```
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Listen for Xdebug",
      "type": "php",
      "request": "launch",
      "port": 9003,
      "hostname": "0.0.0.0",
      "pathMappings": {
        "/var/www/html/":"/home/hogehoge/source/hogehoge"
      }
    },
```

` "/var/www/html/":"/home/hogehoge/source/hogehoge"` が、他の人だと変数を使っていますが、よくわからんのでハードコード（？）しています。 docker-compose.yml で指定している `デプロイ先のディレクトリ:WSL上のソースディレクトリ` です 

あとは、VSCode側で Debugを開き、 `Listen for Xdebug` を起動 (>) すればOK

## 他、メモ
### Containerから通信が来てない？
Terminalで `ns -l -p 9003` で値が来るか待ち受けて、XMLが流れてきたらOK