PHP + VSCode + Docker + Xdebugでコーディングテストor競技プログラミング用の環境構築

# 概要
転職活動の際、コーディングテストを受ける機会があるかと思われます。その際、デバッグしながらアルゴリズムを作成した方が、変数内の動きが分かりやすくなり、アルゴリズムの作成もスムーズになると思ったので作成しました。今回は、その構築手順について簡単に説明します。

# 開発環境
```sh
Docker version 20.10.17, build 100c701
Docker Compose version v2.7.0
```

# ディレクリー構造
ディレクトリーの構成は下記の構造となっています。
```
.
├── .vscode/
│   └── launch.json
├── conf/
│   └── php-xdebug.ini
├── src/
│   └── index.php
├── .gitigrone
├── docker-compose.yml
├── Dockerfile
└── README.md
```

# VScodeの設定
VScodeの拡張機能で、`PHP Debug`をインストールしておいて下さい。
![説明.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664659/9ea4a3c9-e6d7-f1fb-56bd-5693af8ca4fe.png)

# Dockerfile
`php`のバージョンに関しては、ご使用したいバージョンに変更して頂いて大丈夫です。
```Dockerfile
FROM php:8.2-cli

RUN apt-get update && apt-get install -y \
    vim \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# xdebugの処理追加
RUN pecl install xdebug \
    && docker-php-ext-enable xdebug

```

# docker-compose.yml
必要な物があれば、追加して頂いて大丈夫です。
```docker-compose.yml
version: "3.9"
services:
  web:
    build: .
    working_dir: /var/www/html
    container_name: web
    stdin_open: true
    tty: true
    ports:
      - 8080:80
    volumes:
      - ./src:/var/www/html/
      - ./conf/:/usr/local/etc/php/conf.d/
```

# .iniファイル
拡張子が`.ini`であれば何でも大丈夫です。著者は、`php-xdebug.ini`と言うファイル名にしてます。
```php-xdebug.ini
[xdebug]
; Xdebug内、ステップデバッグを有効化
xdebug.mode = debug

; Xdebugの実行ファイルのパスの設定項目。zend_extension=xdebugがデフォルト設定らしい
; xdebug.soのpath： /usr/local/lib/php/extensions/no-debug-non-zts-xxxxxxxx/xdebug.so
zend_extension = xdebug

; PHPの実行時にデバッグを自動的に開始する
xdebug.start_with_request = yes

; 接続先のホスト
xdebug.client_host = host.docker.internal

; 接続先のポート(Xdebug 3は 9003番のportを推奨している)
xdebug.client_port = 9003

; ログを表示するディレクトリの指定(コンテナー内に入れば確認可能)
xdebug.log=/var/log/xdebug.log
```

# launch.json
VScodeのサイドバーに`実行とデバッグ`の項目があるので、`launch.json`の作成を行います。
追加する内容は、`pathMappings`の項目だけで大丈夫です。
```launch.json
 "version": "0.2.0",
  "configurations": [
    {
      "name": "PHP debug",
      "type": "php",
      "request": "launch",
      "hostname": "0.0.0.0",
      "port": 9003,
      "pathMappings": {
        "/var/www/html": "${workspaceRoot}/src"
      }
    },
   
     // 省略

  ]

```

# index.php
`index.php`に下記のコードを記載する事で、コマンドラインからの入力値を受けることができます。
`foreach`を使用している理由として、コマンドラインから入力値をコード側に渡す際、ファイルパスが変数の最初に必ず入る為、それを取り除くべく、`foreach`を使っています。
```index.php
<?php
// $argv コマンドラインから実行したときに、 現在のスクリプトに渡されたすべての引数の配列が含まれます
// $argc コマンドラインから実行したときに、 現在のスクリプトに渡された引数の数が含まれます

foreach ($argv as $key => $v) {
    if ($key == 0) {
        continue;
    }
    $array[] = $v;

}

var_dump($array);
```

# デバッグの実行
サイドバーの、`実行とデバッグ`を押下します。
`実行とデバッグ`と記載された近くに、三角ボタンがあると思いので、それを押下してデバッグモードを起動させます。

![スクリーンショット 2023-01-31 23.19.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664659/95f933f8-65c9-5cba-4928-4bed51a74b9a.png)


## コマンドライン
下記のコマンドをターミナルに打つ事で、`$argv`に入力した値を渡す事ができます。
```sh
docker exec web php ファイル名 標準入力値を入力

# 例 docker exec web php index.php test1 test2 test3
# 今回の環境では、例の記入をターミナルに行う事で、指定した入力値を送ることができる
```

# GitHub
コーディングテスト環境をgithubに記載していますので、詳細内容は確認して頂ければと思います。

https://github.com/kengo-sk8/PHP-coding-test-environment

# 感想
今まで、`launch.json`や`Xdebug`等の設定をなんとなくでやっていたので、今回は詳細に知れて凄く勉強にはなりました。
次は、`python`で同様の環境を作る予定です。競技プログラミングやコーディングテストは、`python`で書いた方が良い的な　記事を何処かで読んだので、`python`でアルゴリズムの勉強をゴリゴリやっていきたいと思います。

# 参考資料
[【ディレクトリ構造を簡単に書けるツール】tree.nathanfriend.io](https://tree.nathanfriend.io/)