Docker内PHP開発環境(2022年水無月)[2/2]

# 初めに

[前回記事[1/2]](https://qiita.com/CinTAKE/items/ef25607d9a2724a049f5)

記事を読んでいただいている読者の皆様、いつもありがとうございます。
DockerによるPHP開発環境が完成したので、その環境にてデバッグ実行をしていく。
前回、当方がgithubで公開したコードには不具合があった。
ビルド途中で止まってしまったり、php-imap拡張がインストールされないなどの問題が発生していた。これは、Dockerfile.dvlの定義にいくつかミスがあったためだ。修正し、現在は正常ビルドできることを確認している。読者の皆様には、この場を借りてお詫びする。(2022/07/12)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/debda0ff-432a-3e6f-04e7-398d56ee7551.png)

まずはdolibarrのインストール作業を進めて正常動作するように設定する。

### Dolibarr インストール・設定
ディレクトリやDBの設定を進めようとすると、DBが使えないとの表示！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/3f6c6fd6-9261-fe57-9f11-fcf71690879d.png)

なんと、PDOではなくて、MySQLiが必要であった。永続化してあるのは、/usr/loca/etcだけなので、Dockerfile.dvlを訂正してライブラリを追加する。(2022/07/12版のコードでは追加済み)

```Dockerfile
# pdoに加えてmysqliを追加し、設定を忘れていたenableも実行
      && docker-php-ext-install \
            iconv pdo pdo_mysql mysqli calendar zip \
      && docker-php-ext-enable \
            intl iconv pdo pdo_mysql mysqli calendar zip \
```
VSCodeの左下の「Remote Development」アイコンをクリックしで、「Rebuild Container」を選択すると、ビルドが始まりMySQLiの拡張が組み込まれる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/e24b9fed-6ac9-e648-590c-7663e72bd933.png)

これでMySQLiが使えるようになったので、インストールを進める。
以下のようにユーザとパスワードはDolibarr用に新規定義。
スーパーユーザはrootを指定し、DBのホスト名とスーパーユーザのパスワードはdocker-compose.yamlにて定義したものを入れる。
「次のステップ」ボタンをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/86584a2a-8018-35cf-e455-b948a202ed03.png)
- - -
<details><summary>MySQLの設定ミスで、既存スキーマ使用時にエラー</summary>

データベース名として「dvldb」(docker-compose.yamlで指定したスキーマ)を使用した場合、「Incorrect string value」などの文字コードがらみのエラーが発生した。
![Dolibarr-dbcharset.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/e3449170-1784-b60a-1f9f-56f4642a3009.png)

これは、MySQLのデフォルト文字セットおよび照合順序が、「latin1、latin1_swedish_ci」であり、漢字などのutf8文字が扱えないからである。よって、MySQLの初期化フラグで文字コードを「Utf8mb4」に指定する必要がある。(Gitでは修正済み)
```
SQLエラー : DB_ERROR_1366 - insert into llx_c_regions (fk_pays, code_region, cheflieu, tncc, nom) values ( 9, 901, '京',0, '北京市'); - Incorrect string value: '\xE4\xBA\xAC' for column 'cheflieu' at row 1
SQLエラー : DB_ERROR_1366 - insert into llx_c_regions (fk_pays, code_region, cheflieu, tncc, nom) values ( 9, 902, '津',0, '天津市'); - Incorrect string value: '\xE6\xB4\xA5' for column 'cheflieu' at row 1
SQLエラー : DB_ERROR_1366 - insert into llx_c_regions (fk_pays, code_region, cheflieu, tncc, nom) values ( 9, 903, '沪',0, '上海市'); - Incorrect string value: '\xE6\xB2\xAA' for column 'cheflieu' at row 1
```

:::note info
docker-compose.yaml の MySQL 初期化フラグとして、文字コード指定を追加。(それ以外のものは、旧システムとの互換性のための設定)
    command:
    # utf8mb4
    - "--character-set-server=utf8mb4"
    - "--collation-server=utf8mb4_unicode_ci"
    # table名を小文字に
    - "--lower_case_table_names=1"
    # 5.7で「ONLY_FULL_GROUP_BY」を外す
    - "--sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

:::

</details>

- - -

「次のステップ」後に、エラー表示されるが、アプリの想定上エラーであり、スーパーユーザで作業続行されるため、問題なし。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/305fa3c0-18d8-9806-4f6f-2e0864ca850b.png)

「次のステップ」では少々待ち時間があるが、終わるとまたしてもエラー。
ベータ版ゆえのものかもしれないので、とりあえず次へ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/0710a584-82ba-fe3b-c879-adbfa714aa7f.png)

最終ステップとなり、初期ユーザを設定してインストール終わり。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/00406d27-8ff9-8821-b561-311e061928af.png)

Dolibarrに移動で、ログイン画面となる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/e3be3d5d-3c33-e100-d807-f5ecadc3d003.png)

最後のステップで設定した初期ユーザでログインする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/4946f4ab-54e0-2be2-86d8-2a35a7e99f63.png)

ログインすると、初期設定画面となる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/5c8230bb-9115-4f09-236b-564b74eb6e2d.png)

# Debug機能を設定する
VSCodeからPHPコードをデバッグするため、定番のXDebugを利用する。
Dockerfile.dvlにて拡張機能のインストール自体は済んでいるので、ここではVSCodeでのデバッグ利用の設定方法と、実際にステップ実行までを試してみる。

### VSCode 拡張機能追加
PHP開発向けの拡張機能をVSCodeに追加する。
ホスト側にPHPがなく、Dockerコンテナ内で作業している場合は、自動的にコンテナ側にインストールされる。

１）PHP Intelephenese
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/8036976d-9592-4277-0b68-649e919df11c.png)

２）PHP Debug
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/385723ec-cfdf-0307-5358-88858c875568.png)

### 動作原理

１）クライアント側(本書では、VSCode + PHP Debug)が指定ポートにてリッスン開始
２）XDebug拡張が、設定に応じて上記クライアントに接続
３）クライアント側debug設定を見て、ブレークしたり、ステップ実行
![design-xdebug.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/bcc21b41-ee97-1d8a-e7a6-e8cc9cd4e45d.png)

## PHP-XDebug 設定
本書では、XDebug 3.x に関して記述する。2.xとはパラメータの名称が変わっているので、注意されたい。
ワークスペースにあるリンク「SH_opt_conf」の中に、ApacheやPHPの実行時に使用される設定ファイル類がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/9f785732-663b-e7cd-9093-1e61f6b98d47.png)

「usr_local_etc_php_conf.d_docker-php-ext-xdebug.ini」ファイルがxdebugの設定ファイルであり、/usr/local/etc/php/conf.d/にリンクか作ってあり、連携している。

```docker-php-ext-xdebug.ini
;; /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
zend_extension=xdebug
xdebug.mode=debug
; xdebug.show_error_trace=1
; xdebug.max_nesting_level=512
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.discover_client_host=1
xdebug.client_port=9103
; xdebug.log=/tmp/xdebug.log
```

:::note info
xdebug.mode の設定値および有効化される機能の一覧
off : すべて無効
develop : Development Helpersおよびvar_dump()
coverage : Code Coverage Analysis
debug : Step Debugging
gcstats : Garbage Collection Statistics
profile : Profiling
trace : Function Trace
:::

### VSCode 設定

それでは、デバッグ機能を起動しよう。左側にある「蟲が付いた三角」のマークを押して、実行とデバッグを開始する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/47af0db9-1339-867e-4b4f-a888ee719b5b.png)

一番最初(launch.jsonファイルが存在しない場合)は、以下のように「実行とデバッグ」ボタンが表示され、その下に「launch.jsonファイルを作成」というリンクが表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/e4198c0c-0ceb-2c30-0028-c575e7b9ec67.png)

ポートがデフォルトとは違っているので、「launch.jsonファイル」を修正する必要がある。リンクをクリックするとプルダウンで選択肢が出るので、「PHP」を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/69f3cd8e-8116-be7a-b3c7-0c9701194c49.png)

<details><summary>すでに「launch.jsonファイル」が存在する場合は、</summary>

ギアマークを押してファイルを編集し、必要な設定を追加・修正する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/c79f9ac8-a588-eaec-4f2d-c3e6834a931e.png)

</details>

ポートなどを修正(9003=>9103)して保存。
使用するのは、先頭部分の「"name": "Listen for Xdebug"」の設定のみ。

```json{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for Xdebug",
            "type": "php",
            "request": "launch",
            "port": 9103
        },
        {
            "name": "Launch currently open script",
            "type": "php",
            "request": "launch",
            "program": "${file}",
            "cwd": "${fileDirname}",
            "port": 0,
            "runtimeArgs": [
                "-dxdebug.start_with_request=yes"
            ],
            "env": {
                "XDEBUG_MODE": "debug,develop",
                "XDEBUG_CONFIG": "client_port=${port}"
            }
        },
        {
            "name": "Launch Built-in web server",
            "type": "php",
            "request": "launch",
            "runtimeArgs": [
                "-dxdebug.mode=debug",
                "-dxdebug.start_with_request=yes",
                "-S",
                "localhost:0"
            ],
            "program": "",
            "cwd": "${workspaceRoot}",
            "port": 9103,
            "serverReadyAction": {
                "pattern": "Development Server \\(http://localhost:([0-9]+)\\) started",
                "uriFormat": "http://localhost:%s",
                "action": "openExternally"
            }
        }
    ]
}
```

保存し終わると、左上のプルダウンでデバッグ実行の方式を選択できるようになる。「Listen for Xdebug」を選択して左の三角マークを押すとXdebugとの通信ができるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/2a3a8aa1-6073-6a8a-a610-98498925073e.png)

ステップ実行用のツールバーも表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/b1cfc166-e22f-118b-c999-8facd1bc27f2.png)

## 接続

実際にブレークポイントを設定し、ブラウザからアクセスしてみる。
dolibarr/htdocs/index.php を表示させ、GETやPOSTのパラメータを扱う部分にブレークポイントを置く。行番号の左側をクリックすると赤いマークが灯くので、そこがブレークポイントとなる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/81d90e05-1ee2-6a48-3b09-b2ae25a36bb4.png)

左下のブレークポイント一覧にもチェックマーク付きで表示される。
この部分からブレークを外すこともでき、Exceptionなどのイベントでブレークするように指定することもできる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/635ffaa6-b0ed-023f-8752-9d6d2d0a6346.png)

場合によっては、赤マークがグレーの枠だけになり、「未確認のブレークポイント」状態となってしまうことがある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/1840a627-fd56-71c9-483f-2a7a4597771a.png)

そんな場合は、ステップ実行のツールバーにある「ぐるぐるマーク(再起動)」をクリックすると赤マークに復帰する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/79b567eb-4d14-ce0f-8e9a-a2215d356efe.png)

準備できたので、ユーザ名とパスワードを入力して「ログイン」ボタンを押してみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/e491ffab-f0ec-ab05-2bf3-7afe385b036b.png)

ブレークポイントで停止したので、ステップするなり、変数の値を調べるなりしてデバッグできるようになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/cec1c409-0033-acc9-5191-ee7038a0d476.png)

これ以上の説明は多くのライターさんが書いているので、本書では省略する。

## 終了
デバッグ中は、左側の「蟲付き三角」ボタンにセッション数のバッジが表示されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/aeb13980-fd31-7f9f-767b-7a8fe5238782.png)

デバッグを終了するには、ステップツールバーの右端の四角を押して切断を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/fc9857ac-3879-c162-2c6e-9479adaa811d.png)

## ログ
ログ出力場所の設定は、以下のファイルにある。

- SH_opt_conf/etc_apache2_sites-enabled_webapp.conf
- SH_opt_conf/etc_apache2_sites-enabled_000-default.conf

Default(port=81)のログは、stdin,stderrにリダイレクトされているのでVSCodeでは確認不可となっている。ホストPC側にて、docker ps でWebコンテナを見つけて、docker logs <webコンテナID> で確認する。ファイルに出したい場合は、上記「000-default.conf」内のログファイルパスを別のものに変えれば普通のファイルとなって内容を確認できるようになる。

webapp(port=80)のログは、以下の2つのファイルに出力される。logrotateされていないため、適宜ファイルを削除すること。

- PV_var_log/apache2/my-access.log
- PV_var_log/apache2/my-error.log
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/28ac13f0-3ef6-c442-4cae-01051dea5210.png)

-----
説明に使用したコード

https://github.com/korabo/docker-components.git

https://github.com/Dolibarr/dolibarr.git

親記事：[WSL2とVSCで作るWindowsでのDocker内開発環境(2021年睦月)](https://qiita.com/CinTAKE/items/ee348acec54195ef5bd1)

[^1]: [開発環境用MySQL+Admin](https://qiita.com/CinTAKE/items/8dd0e9f570c12caf1572)