Laravel: composer update したら500エラー（このページは動作していません: HTTP ERROR 500）

[結論から読みたい人はコチラ](https://qiita.com/chimayu/items/da893e5f5cef1c02fbb1#%E8%A7%A3%E6%B1%BA%E6%96%B9%E6%B3%95)
（今回は Laravel 6.x での事例を書いていますが、 Laravel 7, Laravel 8, Laravel 9 などでの汎用性はあると思います。）

### 環境

- macOS Catalina（バージョン 10.15.7）
- Laravel 6.x
- docker-compose (PHP 7.3 / nginx 1.9 / Redis 5.0) 

を使用。

```zsh
% php artisan -V
Laravel Framework 6.18.24
```

マシンにプリインストールされているPHPは `7.4.28`

```zsh
% php -v
PHP 7.4.28 (cli) (built: Mar  1 2022 01:37:04) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.28, Copyright (c), by Zend Technologies
```

Dockerで動かしているPHPは `7.3.13`

```zsh
% docker exec -it php bash
bash-5.0#

bash-5.0# php -v
PHP 7.3.13 (cli) (built: Jan 18 2020 03:44:29) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.13, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.13, Copyright (c) 1999-2018, by Zend Technologies
```

### 経緯

既存の設定を何も変えずに `composer update` コマンドを実行してLaravelをバージョンアップしたら、 500エラー（Laravelのエラー画面ではなく、ブラウザの「このページは動作していません: HTTP ERROR 500」表示）になりました。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94442/5b530d9c-26ad-8426-85b1-a5c4a545888f.png)

`composer update` コマンドにより、Laravelのバージョンは `6.18.24` から `6.20.44` に変化。

```zsh
% php artisan -V 
Laravel Framework 6.20.44
```

`.env` ファイルは元々存在し、1年半ほど内容は変わっていません。

Dockerの再起動とブラウザでのキャッシュ強制クリア、プロジェクト内のファイル・ディレクトリを全て `chmod -R 777` で権限変更してみたのに加え、念のため下記コマンドも試しました。

```
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
composer dump-autoload
php artisan clear-compiled
php artisan optimize
php artisan config:cache
php artisan key:generate
```

`storage/logs/laravel-2022-xx-xx.log` のファイルでは特にエラーらしいログはありません。

docker/phpのログは以下です。

```
% docker-compose logs php
php      | xxx.xx.x.x -  11/Mar/2022:09:50:50 +0000 "GET /index.php" 500
```

docker/nginxのログは以下です。

```
nginx    | {"time": "2022-03-11T09:53:41+00:00","host": "xxx.xx.x.x","vhost": "localhost","user": "-","status": "500","protocol": "HTTP/1.1","method": "GET","path": "/","req": "GET / HTTP/1.1","size": "5","reqtime": "0.005","apptime": "0.005","ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X xx_xx_x) AppleWebKit/xxx.xx (KHTML, like Gecko) Chrome/xx.x.xxxx.xx Safari/xxx.xx","forwardedfor": "-","forwardedproto": "-","referrer": "http://localhost/"}
```

## 解決方法

ウェブサーバもPHP自体も一応は動いているようだったので、 `public/index.php` のファイルに以下を追記しました。（こちらを試す方は、デバッグ用なので忘れず削除してください。）

```php:public/index.php
ini_set("display_errors", On);  
error_reporting(E_ALL);  
```

**結果**
```php
Fatal error: Composer detected issues in your platform: Your Composer dependencies require a PHP version ">= 7.4.0". You are running 7.3.13. in /data/www/project/vendor/composer/platform_check.php on line 24
// 致命的なエラー：Composerがプラットフォームで問題を検出しました：Composerの依存関係にはPHPバージョン ">=7.4.0"が必要です。 7.3.13を実行しています。 /data/www/project/vendor/composer/platform_check.phpの24行目
```

Laravelを使用するにあたり依存関係にあるパッケージで、PHPのバージョンが合わずに人知れずエラーを吐いていたようです。

`composer.lock` のファイルを見てみると以下の記述がありました。
```json
{
   "name": "psr/container",
   "version": "1.1.2",
   "source": {
    // 〜中略〜 //
   "require": {
       "php": ">=7.4.0"
   },
}
```
確かにエラー文にもある通り、PHP 7.3 で動かそうとしているのに `psr/container: v1.1.2` は PHP 7.4 以上が必要だったからダメだったんですね。

では、`psr/container` のパッケージを使っていそうな箇所を見てみましょう。
`composer.json` のファイルに記載されたパッケージ名を順番に [Packagist](https://packagist.org/) で確認したところ...。
 `laravel/framework` 内で `psr/container` のパッケージを使用しているみたいでした。

[laravel/framework: v6.20.44](https://packagist.org/packages/laravel/framework#v6.20.44)

ただこちらを見る限りでは、`psr/container: ^1.0` とのことで `psr/container` のバージョンは 1.1.2 である必要はなく、1 以上であれば良いようです。

次に、同じく Packagist で、`psr/container` のパッケージについても見てみます。version 1.1.2 では PHP 7.4 以上が必須要件だったので、試しにひとつ下の version 1.1.1 について確認します。

[psr/container: v1.1.1](https://packagist.org/packages/psr/container#1.1.1)

動作要件を見ると...

> **requires**
> php: >=7.2.0

とあるので、今の環境である PHP 7.3 でも動きそうです。

というわけで `psr/container` のバージョンを固定するため、 `composer.json` のファイルに下記を追加しました。
```json
   "require": {
       // 〜中略〜 //
       "psr/container": "1.1.1" // ←追加
   },
```

`composer update` のコマンドを実行して、500エラーは解消です！

### 分析

そもそも、何故このバージョンミスマッチが発生したのか？ということですが。
前述のように

> PHP 7.3 で動かそうとしているのに `psr/container: v1.1.2` は PHP 7.4 以上が必要だったからダメ

だったわけですが、その辺のバージョンをいい感じに合わせてくれるのが Composer じゃないの？？？
という気持ちはいったん置いて、思い出してください、実行環境がどうなっていたかを。。。

> マシンにプリインストールされているPHPは `7.4.28`

> Dockerで動かしているPHPは `7.3.13`

要するに、Docker内部で `composer update` のコマンドを実行できれば問題なかったのですが、そうではなくホストマシン側で `composer update` をしていたため、 Composer さんは実行環境が `PHP 7.4.28`だと思ってアップデートしてくれていたわけですね。

#### 古いバージョンのPHP7.3系をインストールして検証

検証のため、マシンにプリインストールされているPHPを `7.3系` にダウングレードして`composer update` をしたところ、無事（？） 500 Internal Server Error になることもなく、`composer.json` のファイルに無駄な追記をすることもなく、Laravelのアップデートができたのでした。。。

ちなみに、古いバージョンのPHPをインストールする際はコチラを参考にしました。
[Mac Catalina 10.15 に、古いバージョンのPHPをインストールする](https://qiita.com/kaihei777/items/7e054e5b2e018fa7a271)

そもそも PHP 7.3 はセキュリティサポートも終了してますし、 7.4系で合わせるか、なんなら PHP 8.0系/8.1系もリリースされたのでそちらを使えば良いんですけどね。
ただ [Laravel 6 は PHP 8.0系までがフルサポート？](https://github.com/laravel/framework/pull/33388)なので、Laravel自体も8とか9とかにバージョンアップしていきたいところです。

*（この後めちゃくちゃPHPとLaravelをバージョンアップした...）*

#### 参考URL:
[PHPで500エラーを返すと真っ白で表示されない、発生した原因と対策](https://urashita.com/archives/21930)
[PHPのリリース日とサポート期限](https://qiita.com/bezeklik/items/72d1ff8393f66673e2bc)
[docker docker-compose コマンド](https://qiita.com/souichirou/items/6e701f6469822a641bdd)
[【Laravel】6.x〜7.6.2にバージョンをあげたお話](https://tektektech.com/laravel-6-x%E3%80%9C7-6-2-version-up/)
[PHP 8.1 がリリース！だけど思わぬ落とし穴も](https://qiita.com/t_arase/items/817baa417d05590a4f38)
[LaravelのPHP8のサポートバージョンは？](https://kusumo-t.com/laravel8-php8/)
[The max php functions behaves differently depending on the PHP Version](https://github.com/laravel/framework/pull/37163)