【Wordpress】一部ページが「重大なエラーが発生しました」＆サイトヘルスで「1つ以上の必須モジュールが存在しません」が表示された場合

# 概要
* テスト環境で構築したWordpressを本番環境の別サーバーに引っ越したら、一部のページが「重大なエラーが発生しました」と表示されてしまうエラーに悩まされました。2日くらい消費したので、どなたかの一助になればと思い、まとめておきます。
* Wordpressのサイトヘルスで「1つ以上の必須モジュールが存在しません」というエラーも出ていたので、そちらに直面している方にも参考になるかもです。

## 環境
* Mac
    * 機種ID：MacBookPro18,3
    * macOS：Monterey
    * チップ：Apple M1 Pro
    * メモリ：16GB
* サーバー（AWS EC2インスタンス）
    * OS：Ubuntu 18.04.3 LTS
    * Web Server：Apache/2.4.29
    * Wordpressバージョン：6.1.1
    * PHPバージョン：7.4.33

## 前提
* 上記サーバー情報は、テスト環境でも本番環境でも同じ。
* 変なプラグインはなし（WordPress ImporterとContact Form 7しか有効化されていない）。
* 変なテーマは利用していない。推奨PHPバージョンは7.4以上で、テスト環境では正常に機能している。
* テスト環境でWordpressを無事に構築できたので以下の順序でWordpressを引っ越し。
    * 構築手順の記事はこちら：[WordpressをEC2インスタンスにインストールする方法（Apacheのバーチャルホスト設定方法・Wordpress用DB作成方法も解説）](https://qiita.com/Ryo-0131/items/a6dab55ea5b54b6e10b7)
    * Wordpress管理画面の「ツール」から「全てのコンテンツ」をエクスポート(XMLファイル)
    * 本番環境のWordpress管理画面でWordpress Importerを利用してインポート
    * テスト環境と同じ有料テーマをアップロード
        * アップロードサイズエラーが出た際はこちら：[【Wordpress】アップロード時の"upload_max_filesize"エラーと"Unable to create directory"エラーを対応](https://qiita.com/Ryo-0131/items/a0133f6e37bcb8d32592)
    * 有料テーマを利用しているので、テスト環境のテーマオプション管理からエクスポートしたJsonファイルをインポート
* ちなみに、他にもプラグインを使って引っ越しする方法がありますが、データ破損のリスクやアップロードサイズ上限、課金制度などがあったので、やめました。ちょっとトライしましたが、アップロードサイズのところがうまくできんかった。

## エラー内容
* テスト環境と同じくサクッと構築できると思ったら、なぜか一部ページで「重大なエラーが発生しました」が表示されてしまいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/c0786d17-0190-aec2-7eb4-09aa184e5936.png)

* えぇぇ！？こりゃ焦るやつや
* phpmyadminに入ろうとしてもこんな画面になってしまう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/88982570-1add-02fd-ad70-6a7fe082ae60.png)

* テスト環境では難なくできたのに...サイトヘルスをチェックすると以下のように表示されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/21a142e2-d78c-93e9-3e6e-43575a94e00b.png)

* 「1つ以上の必須モジュールが存在しません」というエラーは、PHP拡張モジュールがインストールされていないことが原因のよう。
* サイトヘルスの「情報」タブをクリックすると、imagickやgdが利用できないことがわかります。おそらくこの辺に問題があることはなんとなく分かりますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/c521cafb-ef33-6255-8975-7fe02b501029.png)

## やってみたこと
* 以下を実施しましたが、いずれもダメでした。

### 不足しているモジュールをインストール
* 存在しないと言われているモジュールをapt installで一個ずつ普通にインストール

```bash
$ sudo apt-get install php-gd
```
* `php -m`でモジュールが有効なことは確認できるが、エラーは変わらず

### `php.ini`で拡張機能を有効化する
* いろいろな記事に、PHPの設定ファイル`php.ini`で有効化する（拡張機能が正しくロードされるように設定する）必要がある、と記載があったので、`/etc/php/7.4/apache2`にある`php.ini`に各モジュールの有効化を記載します。
    * 元から`;`でコメントアウトされている場合は外すでもOK

```conf
extension=curl.so
extension=imagick.so
extension=mbstring.so
extension=zip.so
extension=gd.so
extension=intl.so
```

* Apache再起動してみる。しかし、、、結果は変わらず。
* ちなみに、`apache2`だけでなく`cli`や`fpm`直下にある`php.ini`にも追記してみたけど何も変化なし。
    * `/etc/php/7.4/apache2`にある`php.ini`：Apache Webサーバーを使用してPHPスクリプトを実行する場合に読み込まれる設定ファイル
    * `/etc/php/7.4/cli`にある`php.ini`：PHPコマンドラインインターフェース（CLI）を使用してPHPスクリプトを実行する場合に読み込まれる設定ファイル
    * →どちらも記載は必要だと思いますが、Apacheは2回読み込むことになるのか、以下のエラーログが吐き出されていました。PHPが各モジュールをすでに読み込んでいるので、同じ場所で再度読み込まれている、というメッセージですね。

```
PHP Warning:  Module 'curl' already loaded in Unknown on line 0
PHP Warning:  Module 'gd' already loaded in Unknown on line 0
PHP Warning:  Module 'imagick' already loaded in Unknown on line 0
PHP Warning:  Module 'intl' already loaded in Unknown on line 0
PHP Warning:  Module 'mbstring' already loaded in Unknown on line 0
PHP Warning:  Module 'zip' already loaded in Unknown on line 0
```

* 特に問題があるわけではないと思いますが、複数回読み込まれるログが鬱陶しい場合は`/etc/php/7.4/apache2`のみに記載でOKです。（本件解決後、自分の場合はそれで動いています）

### デバッグモードで確認
* `wp-config.php`でデバッグモードを追記

```php
define( 'WP_DEBUG', false )
```

* Apacheを再起動、エラーページを見てみるが、「重大なエラー」だけで、何も出てこない。
* 次に、`wp-config.php`でデバッグエラーログを吐き出させるよう設定する

```php
define( 'WP_DEBUG_LOG', true )
```

* 中身を見てみるとほとんど有料テーマ関連の警告ばかり。

```
PHP Notice:  Undefined index: catch_font_type in...
```

* うーん、特にこれが問題ではなさそう（結果、やっぱり関係なかった）。

### LoadModule php7_moduleを入れてみる・パーミッションを確認する
* PHPのバージョンとApacheを連携させる必要があるという記事もあったので、`LoadModule php7_module modules/libphp7.4.so`をApacheの設定ファイル`/etc/apache2/apache2.conf`に入れてApache再起動してみるが、やはりだめ。
   * 参考：[PHP7.3とApacheを連携させる方法](https://www.koikikukan.com/archives/2021/06/21-235555.php)
* 読み込みアクセス権限やパーミッション（ディレクトリのパーミッションは「755」にするなど）の問題かと思い、正常に動いているテスト環境のものと見比べたが、問題なし...。
* ど、どういうこと...(⌒-⌒; )

## 解決手順
* 調べてみると、apache2.4のエラーログがあるらしい。`/var/log/apache2`にある`error.log`を見てみると、こんなエラーメッセージがずらずらと並んでいるではありませんか。これ、サイトヘルスのと同じモジュールだ。

```log
PHP Warning:  PHP Startup: Unable to load dynamic library 'gd.so' (tried: /usr/lib/php/20190902/gd.so (/usr/lib/php/20190902/gd.so: cannot open shared object file: No such file or directory), /usr/lib/php/20190902/gd.so.so (/usr/lib/php/20190902/gd.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
```

* どうやら、`/usr/lib/php/20190902/`にお探しのファイルがない模様。
    * `/usr/lib/php/20190902`は、PHPの拡張モジュールが格納されているディレクトリのパスです。このディレクトリは、PHP 7.3.xバージョンでのデフォルトの拡張モジュールのインストール先として使用されているらしい（20190902は、PHPのビルド日）。しかし、ここを見てみても、確かに`gd.so`とか`zip.so`が無い。インストールは成功していたけど、PHP7.4が見にいっていないのかもしれない。
* 以下でまず`zip.so`がどこにいるのか探してみる。（zipでもgdでもどれでもいいけどzipで調べてみた）

```bash
$ sudo find / -name 'zip.so'
/usr/lib/php/20170718/zip.so
/usr/lib/php/20220829/zip.so
```

* あれ、お探しの`20190902`にはないぞ。
* 以下コマンドで`zip.so`のシンボリックリンクを置いてあげると、、
    * 参考：[CentOS8+PHP7.4にZipArchiveをインストールする→`PHP Startup: Unable to load dynamic library ‘zip.so’`の警告に対処](https://labor.ewigleere.net/2020/03/23/centos8-php74-ziparchive-install/)

```bash
$ ln -s /usr/lib/php/20220829/zip.so /usr/lib/php/20190902/zip.so
```

* 今度は以下のようにエラーログに記載されていました。

```
PHP Warning:  PHP Startup: Unable to load dynamic library 'zip.so' (tried: /usr/lib/php/20190902/zip.so (/usr/lib/php/20190902/zip.so: undefined symbol: _call_user_function_impl)
```

* エラー内容が微妙に変わってる。シンボリックリンクではうまく読み込めてないっぽい。とにかく正しくロードされていないことがわかる。
* ちなみに、CPコマンドでコピーしてあげても、最初のエラーと同じものが吐き出されるだけだった。

```bash
$ cp -i /usr/lib/php/20220829/zip.so /usr/lib/php/20190902/zip.so
```

* PHPのバージョンとzip拡張機能のバージョンが互換性がないのか？
* そんなことを調べていて目に入ったのが、以下のサイト。
    * 参考：[PHP Warning: PHP Startup: Unable to load dynamic library](https://askubuntu.com/questions/784443/php-warning-php-startup-unable-to-load-dynamic-library)
* ここでは、7.0指定でインストールすると解決するというコメントがあります。

>Something wrong with your configuration, but if you have root access, just install again the missing extensions. For PHP 7.0:
sudo apt-get install php7.0-intl
sudo apt-get install php7.0-soap

* 早速、自分の場合は7.4で実施しました。

```
sudo apt-get install php7.4-intl
sudo apt-get install php7.4-zip
sudo apt-get install php7.4-curl
sudo apt-get install php7.4-imagick
sudo apt-get install php7.4-gd
sudo apt-get install php7.4-mbstring
```

* その後、Apache再起動をすると、なんと見事サイトヘルスから消えました！！うおおおおお！！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/d70e4299-3795-fd8a-b868-80fbe9e9837e.png)

* 「重大なエラーが発生しました」と表示されていたページを開いたら、無事に表示されるようになっていました。

ヤッタァぁぁぁぁあ！！！！

## 結論
* 「重大なエラー」の正体は、Wordpressで必要なPHPモジュールが正常に読み込まれていないことでした。
* phpMyAdminのアクセスエラーもPHPのmbstring拡張機能が有効になっていないために発生していたので、その後アクセスしたら正常にログインできました。
* PHP7.4指定でインストールしてあげないと、Apacheがちゃんと見てくれないわけか。あのエラーログにもっと早く辿り着いていれば。
* 途中、何が原因なのか分からずVirtualHost設定を見たり、有料テーマの中に悪さしているものがあるのか見たりして、かなり遠回りをしてしまいました。困った時はやっぱりエラーログですね。とにかく時間を使ったエラー対応でしたが、サイトヘルスが良好になった瞬間は感動しました...。ググっても大体「インストール」「php.ini」ばかりなので、今回このようにまとめらることでエンジニア同士の一助になれば幸いです。