PHP8 RC、Composer2、Xdebug3 RCでLaravel8.xを動かす

## 概要

- PHP8.0がRCになっていたから諸々新し目のものを使って環境構築してみるよ
- 環境自体はDockerで構築していくよ
- 全ての環境に対応出来るわけじゃないと思うけど参考になれば嬉しいよ
- PHP8.0もXdebug3もRCなので現状は実運用しないように、とはいえ開発していくのには見ていくことも必要だよね

## 最終的な環境

```sh
$ docker-compose exec app php --version
PHP 8.0.0RC4 (cli) (built: Nov 12 2020 20:17:20) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.0-dev, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.0RC4, Copyright (c), by Zend Technologies
    with Xdebug v3.0.0RC1, Copyright (c) 2002-2020, by Derick Rethans

$ docker-compose exec app composer --version
Composer version 2.0.7 2020-11-13 17:31:06
```

## 成果物

GitHubにあげてあるので参考にどうぞ
Dockerfileの最終状態もリポジトリにあげてあります

https://github.com/hrs-o/PHP8.0RC-Laravel

## PHP7.4 時代のDockerfile

- この7.4時代のDockerfileを8.0RC用に書き直していくのが主目的

```dockerfile
FROM php:7.4-fpm-alpine

RUN apk upgrade --update && \
    apk --no-cache add autoconf build-base git libxml2-dev libzip-dev oniguruma-dev openssh rsync

RUN docker-php-ext-install -j$(nproc) zip pdo_mysql mysqli
RUN docker-php-ext-install -j$(nproc) bcmath fileinfo ctype json mbstring tokenizer xml
RUN docker-php-ext-install -j$(nproc) opcache

RUN pecl install apcu \
    && docker-php-ext-enable apcu

RUN pecl install xdebug \
    && docker-php-ext-enable xdebug

RUN pecl install redis  \
    && docker-php-ext-enable redis

RUN curl -sS https://getcomposer.org/installer | php \
    && mv composer.phar /usr/local/bin/composer \
    && composer self-update

RUN composer global require hirak/prestissimo
RUN composer global require squizlabs/php_codesniffer
RUN composer global require friendsofphp/php-cs-fixer
RUN composer global require phpmd/phpmd
RUN chmod 777 /var/log/

ENV PATH "/root/.composer/vendor/bin:$PATH"
```

## 試したこと

### Imageを`8.0-rc-fpm-alpine`に変更

当然というか流石にbuild通らず

- `RUN docker-php-ext-install -j$(nproc) json` でコケる
  - 指定せずとも利用出来るので単純に省いた
  - https://wiki.php.net/rfc/always_enable_json
- 現在peclがPHPのイメージから省かれているらしいので使えない
  - https://externals.io/message/103977
  - PHP7.4かららしいけどPHP7.4でpecl通っていたんだけどな……？
  - そのためpeclの代わりに[FriendsOfPHP/pickle](https://github.com/FriendsOfPHP/pickle)を利用検討

### FriendsOfPHP/pickleの利用

- releaseから取得したpickleだとXdebug-betaのVERSIONがうまく取得出来ずエラーになってしまう
- masteをビルドしてね、とのことだがxdebugのbetaのVERSIONがパースエラーになるため利用出来ない
- そのためForkして自リポジトリで修正した状態で利用することに（PR自体は送信済み、受け入れられると嬉しい）
  - 現状pickleはcomposer1でないと利用出来ないのでComposer1のイメージでビルドしてからPHP8.0の方にCOPY
- peclでインストールしていた部分をpickleに変更することでapcu、xdebug-beta、redisのインストールができた

```dockerfile
FROM composer:1 as pickle

RUN cd /tmp \
    && git clone https://github.com/hrs-o/pickle.git \
    && cd pickle \
    && git checkout update/dumper-stability \
    && composer install --no-dev --optimize-autoloader \
    && php -d phar.readonly=0 box.phar build

FROM php:8.0-rc-fpm-alpine

COPY --from=pickle /tmp/pickle/pickle.phar /usr/local/bin/pickle
```

### hirak/prestissimoがインストールできない

- [hirak/prestissimo](https://github.com/hirak/prestissimo)は現状Composer2に未対応のようなので一旦諦め。
  - というかComposer2は高速だからprestissimo使わなくていいよね！ってリポジトリに記載有り。

---

ということでここまでで一応Dockerfileの修正は終わったのでLaravelのインストールと動作確認をしていく。

## Laravelのインストール

```sh
$ mkdir src
$ docker-compose exec app composer create-project --prefer-dist laravel/laravel . "8.*"
```

### .envの設定

DB接続とRedisへの接続を試すので設定しておく

```php:.env
~~
DB_CONNECTION=mysql
DB_HOST=php8-mysql
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=root

~~

REDIS_HOST=php8-redis
REDIS_PASSWORD=null
REDIS_PORT=6379

~~
```

### migrate実行

```sh
$ docker-compose exec app php artisan migrate
```

### View・Contoroller・Roterを定義し実行

内容はコミットを参照してください
https://github.com/hrs-o/PHP8.0RC-Laravel/commit/69e1aae936ff77b6c165c68f5f39576301c697f8

ひとまずDB接続、Redisへの接続も上手く行っていそう

## IDEからリモートデバッグ出来るか確認

今回はIntelliJ Idea（PHPStorm）を対象とする

### Xdebugの設定が変わっているので修正

https://3.xdebug.org/docs/upgrade_guide

```diff:php.ini
[xdebug]
- xdebug.remote_enable = 1
+ xdebug.mode = debug
- xdebug.remote_autostart = 1
+ xdebug.start_with_request = yes
- xdebug.remote_host = host.docker.internal
+ xdebug.client_host = host.docker.internal
- xdebug.remote_port = 9000
+ xdebug.client_port = 9003
- xdebug.remote_log = /tmp/xdebug.log
+ xdebug.log = /tmp/xdebug.log
xdebug.idekey = PHP8
```

### XDEBUGのPort設定

- Languages & Frameworks > PHP > Debug 内のXdebug portを 9003 に変更

### PHP Remote Debugの設定
- Edit Configurations を開く
- 左上の+ を押して PHP Remote Debug を選択
- Filter debug connection by IDE keyにチェックを入れる
- IDE keyに PHP8を入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664/7ccad617-8a26-2bda-f44d-ba21198318d3.png)

- Server の横にある .. を押す
- Serversダイアログ左上にある + を押してサーバーを追加
- Hostに `localhost `を設定
- Portに `58080` を設定
- Use path mappings にチェック
- Project filesのsrcに対応するAbsolute path on the serverに /src を記述してOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1664/d1f27640-af66-e857-b1ab-1d762de2a9fa.png)

### リモートデバッグ実行

- コードの適当なところにブレークポイントを設定
- 作成したPHP Remote Debugをデバッグ実行
- ブレークポイントを設定したコードを通る処理の実行

今回、自分の環境ではステップ実行出来るのは確認済み

## まとめ

- 書いてみると単純なことばかりだけどpickle周りはとてもてこずった
- というかほとんどpickleのソースリーディングと修正に時間かった
- 実際利用する際にはライブラリがcomposer2に対応しておらず使えないこともまだ多そうなので何ともだがPHP8に向けて触っていく位の構築はできたんじゃないかなと

## 参考
[【PHP8.0】PHP8.0の新機能](https://qiita.com/rana_kualu/items/fe7998fbe773544d5d25)
[【PHP8】Docker で PECL の YAML 関数（YAML パーサー）をインストールして使う](https://qiita.com/KEINOS/items/31f1d0b8014d89c788c3)